2011-01-14 37 views
9

Ho uno script Bash che copia ripetutamente i file ogni 5 secondi. Ma questo è un tocco eccessivo come di solito non c'è cambiamento.Script di Bash: determinare se il file è stato modificato?

So del comando di Linux watch ma come questo script sarà utilizzato su computer OS X (che non hanno watch, e io non voglio rendere tutti installare MacPorts) ho bisogno di essere in grado di verificare se un file viene modificato o meno con codice Bash dritto.

Devo controllare il tempo di modifica del file? Come lo posso fare?

Modifica: Speravo di espandere il mio script per fare altro che copiare il file, se ha rilevato una modifica. Quindi c'è un modo puro per farlo?

+0

Forse si può usare 'rsync' invece? Può confrontare il timestamp e le dimensioni con il timestamp e le dimensioni del file di destinazione ed evitare di copiare se sono uguali. (Se stai copiando su una scatola remota, ci sarà comunque il sovraccarico della connessione.) – Thomas

risposta

13

tendo a concordare con la risposta rsync se si dispone di grandi alberi di file da gestire, ma è possibile utilizzare il -u (--update) bandiera per cp per copiare il file (s) sopra solo se il la fonte è più recente della destinazione.

cp -u

Modifica

Dal momento che hai aggiornato la questione per indicare che si desidera prendere alcune azioni aggiuntive, ti consigliamo di utilizzare il check--nt in il [ (test) comando incorporato:

#!/bin/bash 

if [ $1 -nt $2 ]; then 
    echo "File 1 is newer than file 2" 
else 
    echo "File 1 is older than file 2" 
fi 

Dalla pagina man:

file1 -nt file2 
     True if file1 is newer (according to modification date) than 
     file2, or if file1 exists and file2 does not. 

Spero che questo aiuti.

0

No. Si dovrebbe usare rsync o una delle sue interfacce per copiare i file, poiché rileverà se i file sono diversi e li copierà solo se lo sono.

+5

'rsync' è un suggerimento utile (anche se come puoi vedere nella mia modifica, non proprio quello di cui ho bisogno). Ma trovo il tuo tono un po 'scoraggiante. –

+1

@Alan H .: Forse mi manca qualcosa ma non trovo affatto il tono che offende. In effetti sono rimasto sorpreso dalla tua risposta. –

3

Potrebbe risultare più affidabile rilevare le modifiche nel contenuto del file confrontando le dimensioni del file (se le dimensioni differiscono, il contenuto lo fa) e l'hash dei contenuti. Probabilmente non importa molto quale hash usi per questo scopo: SHA1 o anche MD5 è probabilmente adeguato, e potresti scoprire che il comando cksum è sufficiente.

I tempi di modifica dei file possono cambiare senza modificare il contenuto (si pensi al numero touch file); i tempi di modifica dei file non possono cambiare anche quando il contenuto lo fa (è più difficile, ma è possibile utilizzare touch -r ref-file file per impostare i tempi di modifica di file in modo che corrispondano a ref-file dopo aver modificato il file).

+0

Perché utilizzare un confronto hash anziché bit per bit? Il confronto bit-a-bit non sarà più veloce dell'esecuzione dell'intero file e della creazione di un hash di esso? – Pacerier

+1

@Pacerier: se i file sono diversi, il confronto byte per byte potrebbe essere più veloce a meno che l'ultimo byte sia l'unico diverso. Se i file sono uguali, puoi solo mostrarli confrontando tutti i byte. Il vantaggio di un hash è che è possibile memorizzare il vecchio valore dell'hash (che è relativamente piccolo) e confrontarlo con il nuovo valore dell'hash rigenerato dal file corrente. Se c'è una differenza, il file è cambiato. Fare il confronto byte per byte richiede che il vecchio file sia presente. –

6

OS X ha il comando stat. Qualcosa di simile a questo dovrebbe dare il tempo di modifica di un file:

stat -f '%m' filename 

L'equivalente GNU sarebbe:

stat --printf '%Y\n' filename 
Problemi correlati