2010-06-16 9 views
29

considerare qualcosa di simile:Va bene usare lo stesso file di input come output di un comando piped?

cat file | command > file 

è questa buona pratica? Questo potrebbe sovrascrivere il file di input nello stesso momento in cui lo stiamo leggendo, o viene sempre letto prima in memoria e poi inviato al secondo comando?

Ovviamente, posso usare i file temporanei come tappa intermedia, ma mi chiedo solo ..

t=$(mktemp) 
cat file | command > ${t} && mv ${t} file 

risposta

44

No, non è ok. Tutti i comandi in una pipeline vengono eseguiti contemporaneamente e la shell prepara i reindirizzamenti prima di eseguire i comandi. Quindi, è probabile che il comando sovrascriva il file prima che il gatto lo legga.

È necessario sponge(1) da moreutils.

+0

grazie, moreutils sembra molto utile! Lo stesso vale per il reindirizzamento: 'comando < file > file' o anche per la sostituzione di processo:' comando <(cat file) > file'? – Amro

+2

Sì, vale anche in entrambi i casi. Tieni presente che la shell è libera di configurare i reindirizzamenti in qualsiasi ordine, pertanto è necessario considerare il comportamento non definito per accedere due volte allo stesso file in un singolo comando o pipeline. Anche se funziona occasionalmente, non è garantito. – Juliano

3

È inoltre possibile utilizzare qualcosa di simile (non raccomandato, utilizzare i file espliciti temporanei nel codice di produzione):

{ rm file && your_command > file; } < file 
0

Non solo si dovrebbe non scrivere l'output al vostro ingresso, ma anche si dovrebbe evitare loop tua restituire al tuo input.

Quando si tratta di file di grandi dimensioni, ho cercato

cat *allfastq30 > Sample_All_allfastq30 

ed è generato messaggi di errore:

cat: Sample_All_allfastq30: input file is output file 
Problemi correlati