GNU/Linux >> Linux Esercitazione >  >> Linux

Determinare se il file è in fase di scrittura?

Soluzione 1:

La soluzione migliore è usare lsof per determinare se un file è stato aperto da qualsiasi processo:

#  lsof -f -- /var/log/syslog
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
rsyslogd 1520 syslog    1w   REG  252,2    72692 16719 /var/log/syslog

Non puoi dire facilmente se è in fase di scrittura, ma se è in fase di scrittura, DEVE essere aperto.

Modifica:risolviamo qui il vero problema piuttosto che provare a implementare la soluzione proposta!

Usa rsync per trasferire il file:

○ → rsync -e ssh remote:big.tar.gz .

In questo modo, il file non verrà copiato sopra quello esistente ma copiato in un file temporaneo (.big.tar.gz.XXXXXX ) fino al completamento del trasferimento, quindi spostato in posizione.

Soluzione 2:

Sei sulla buona strada, rinominare il file è un'operazione atomica, quindi eseguire la rinomina dopo il caricamento è semplice, elegante e non soggetto a errori. Un altro approccio che mi viene in mente è usare lsof | grep filename.tar.gz per verificare se il file è in fase di accesso da parte di un altro processo.

Soluzione 3:

Un po' datato, ma la maggior parte delle risposte manca completamente il punto della domanda:

Ma ho pensato di provare a capire se c'è semplicemente un modo per determinare se il file è intero prima dalla riga di comando...

In generale non c'è. Semplicemente non hai abbastanza informazioni per determinarlo.

Perché determinare che il file è chiuso non equivale a determinare se il file è intero . Ad esempio, un file verrà "chiuso" se la connessione viene persa durante il trasferimento.

Solo la risposta di @ Alex ha capito bene. E anche lui si è innamorato dell'uso di lsof un po'.

Per determinare se il file è stato completamente trasferito correttamente, sono necessari più dati. Ad esempio:

Un'alternativa a cui stavo pensando era di copiare il file con un'estensione di file diversa (come .tar.gz.part ) e poi rinominato in .tar.gz al termine del trasferimento.

Questo è un modo perfetto per comunicare che il file è stato trasferito completamente e con successo. Puoi anche spostare i file da una directory all'altra fintanto che rimani all'interno dello stesso filesystem. Oppure chiedi al mittente di inviare un filename.done vuoto file per segnalare il completamento.

Ma tutti i metodi devono fare affidamento sul mittente che in qualche modo segnala che il trasferimento è stato completato con successo. Perché solo il mittente ha queste informazioni.

Alcuni formati di file (come i PDF) contengono dati che consentono di determinare se il file è completo. Ma devi aprire e leggere praticamente l'intero file per scoprirlo.

lsof ti dirà solo che il file non è più aperto, non ti dirà perché non è più aperto. Né ti dirà quanto dovrebbe essere grande il file.

Soluzione 4:

Il modo migliore per farlo è usare incron ("inotify cron system"). Ti consente di impostare un controllo inotify su una directory che ti avviserà quindi delle operazioni sui file. In questo caso, dovresti guardare la directory per un close_write. Ciò ti consentirà di eseguire il tuo comando una volta che il file è stato chiuso dopo una scrittura.

Soluzione 5:

Sembra che lsof possa rilevare in quale modalità è aperto un file:

lsof -f -- a_file
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
cat     52391 bob    1w   REG    1,2       15 19545007 a_file

Vedi dove dice 1w? Ciò significa che il numero del descrittore di file è 1 e la modalità è w, o write.


Linux
  1. 7 modi per determinare il tipo di file system in Linux (Ext2, Ext3 o Ext4)

  2. Come determinare quale processo sta creando un file?

  3. Il Bash '?

  4. Mv Atomic è sulle F?

  5. Tail -f, Determina se un file non viene più scritto?

Introduzione al file system Linux

Utilizzo del file di configurazione SSH

Il valore massimo dell'ID di processo?

Come posso determinare se il filesystem fa distinzione tra maiuscole e minuscole in .net?

Comportamento di rsync con il file che è ancora in fase di scrittura?

Come trovare il file .pid per un determinato processo