Il mio problema (in uno script con #!/bin/sh
) è il seguente: provo a fare il checksum di tutti i file in una directory a scopo di archiviazione. Il file checksum (nel mio caso sha1) con tutti i nomi di file dovrebbe risiedere nella stessa directory. Diciamo che abbiamo una directory ~/test
con file f1
e f2
:.
mkdir ~/test
cd ~/test
echo "hello" > f1
echo "world" > f2
Ora calcolando i checksum con
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum
fa esattamente quello che voglio, elenca solo tutti i file della directory corrente e calcola le somme sha1 (maxdepth può essere modificato in seguito). L'output su STDOUT è:
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
Sfortunatamente, quando provo a salvarlo in un file con
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum > sums.sha1
il file risultante visualizza il checksum per se stesso:
da39a3ee5e6b4b0d3255bfef95601890afd80709 sums.sha1
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
e quindi fallisce in un secondo momento shasum --check
, a causa dell'ovvio problema di ulteriori modifiche al file durante il salvataggio dell'ultima somma.
Mi sono guardato intorno e usando -p
flag per xargs
ho scoperto che in qualche modo crea il file di output prima ancora di eseguire il comando find, quindi il file aggiuntivo viene trovato e verrà sommato ...
So che, come soluzione alternativa, potrei salvare il checksum in un'altra posizione (directory temporanea tramite mktemp
) o escluderlo in find in modo specifico, ma mi piacerebbe capire perché si comporta in questo modo - che ai miei occhi non è così utile, ad esempio se il primo comando controlla se il file di output è già su disco, non otterrà mai la risposta corretta ...
sh
sono necessarie più invocazioni. Si noti che è necessario un argomento per $0
prima {}
.
tee
è svanita? L'ho provato e funziona benissimo, ho anche eliminato STDOUT con l'aggiunta di 1>/dev/null
. C'era qualcosa che non andava nella risposta o era un bug?
xargs
, è la shell stessa che crea questo file, perché prima che qualsiasi comando venga eseguito la shell reindirizza tutti gli input, output e pipe, in modo che quandofind
inizia il file di output esiste già. Utilizzare-exec
invece:find -maxdepth 1 -type f -exec sh -c 'shasum "$@" > sums.sha1' {} +