Come è legale questo comando? “> File1 <file2 cat”


61

Supponendo che file2esista già, il comando

> file1 < file2 cat

sembra essere la copia del contenuto di file2a file1.

Ma non riesco a capire questa struttura.

Comprendo che "Nothing" è stato indirizzato a file1(creando o cancellando il suo contenuto). Quindi il contenuto di file2viene indirizzato a file1.

Perché è catdopo file2? come fa a sapere cat file2se gli operandi non sono nell'ordine corretto?


11
Quale "ordine corretto"? Potete fornire un collegamento ad alcune risorse / materiale di apprendimento in cui è descritto un "ordine corretto"?
Lightness Races con Monica

7
Quando fai domande come questa, dovresti specificare la shell; quelli diversi hanno casi limite diversi, specialmente per quanto riguarda il reindirizzamento.
Chrylis

Risposte:


117

Prima che la shell esegua il catcomando dalla riga di comando, cerca i reindirizzamenti.

Esistono due reindirizzamenti:

  1. >file1 Questo farà andare l'output standard del comando file1.
  2. <file2 Questo renderà l'input standard del comando da file2.

Il fatto che questi reindirizzamenti siano collocati in una posizione traballante sulla riga di comando non ha importanza.

$ cat <file2 >file1

equivale a

$ <file2 cat >file1

che è lo stesso di

$ <file2 >file1 cat

etc.¹

Si noti che l' catutilità in tutte queste istanze viene eseguita senza alcun argomento della riga di comando . I reindirizzamenti non sono operandi al catcomando, sono istruzioni alla shell per impostare i reindirizzamenti dentro e fuori il comando (collegando l'input e l'output standard ai file). La shell imposta i reindirizzamenti prima di invocare il comando.

La differenza tra cat filee cat <file(o, se vuoi, <file cat) è che nel primo caso, l' catutilità stessa sta aprendo il file, che viene dato come operando sulla riga di comando, per leggere, mentre nel secondo caso, la shell sarà apri il file e connetti catil flusso di input ad esso². Nel secondo caso, catnoterà che non è stato assegnato un operando di file e passerà automaticamente alla lettura dal suo input standard. Questa è una caratteristica di cat, e di alcune altre utility, non qualcosa che fanno tutte le utility.

catleggerà anche dal suo input standard se viene dato l'operando -. Ancora una volta, questo è speciale solo per cate per alcune altre utilità (cioè niente che la shell fa). Per utilizzare catsu un file nella directory corrente il cui nome è - , aggiungere un percorso al nome file, ad esempio ./-.

¹ L'ordine dei reindirizzamenti è ancora importante in alcune circostanze; Con cat <file2 >file1, ad esempio, file1non verrà troncato se file2inaccessibile (i reindirizzamenti vengono analizzati da sinistra a destra). Il posizionamento relativo della parola catè comunque ancora arbitrario e non influenzerà questo.

² Vedi anche la domanda " cat dà un errore diverso quando si apre un file inesistente ".


Il fatto che la shell imposti i reindirizzamenti prima ancora di eseguire il comando sulla riga di comando è il motivo per cui cose come queste falliscono e si finisce con un file di output vuoto:

$ sort file >file

Qui, la shell tronca (svuota) il file fileprima di eseguire sort filee connettere sortl'output standard al file. L' sortutilità quindi aprirà filee ordinerà il suo contenuto (che è nulla). Il risultato (nulla) viene passato attraverso il flusso di output standard a file.

Il rimedio in questo caso particolare (per ordinare un file "sul posto") è

$ sort -o file file

o

$ sort file >file.sorted && mv file.sorted file

che è più o meno ciò che sortfa quando si utilizza il -ofile per specificare il nome del file di output.


Solo per eseguire il backup dell'affermazione che i reindirizzamenti possono precedere il nome effettivo dell'utilità sulla riga di comando:

Un "comando semplice" è una sequenza di assegnazioni e reindirizzamenti variabili facoltativi, in qualsiasi sequenza, facoltativamente seguiti da parole e reindirizzamenti, terminati da un operatore di controllo. [ref: POSIX Shell Command Language 2.9.1 Comandi semplici]

E anche sul reindirizzamento che non fa parte degli operandi dell'utilità:

Il numero facoltativo, l'operatore di reindirizzamento e la parola non devono apparire negli argomenti forniti al comando da eseguire (se presenti). [ref: POSIX Shell Command Language 2.7 Reindirizzamento]


14
@Steve La libertà di spostare i reindirizzamenti può essere utilizzata per rendere più chiari alcuni comandi, come una pipeline con il reindirizzamento di input all'inizio <in foo | bar >outmette tutto in ordine logico. Mi piace anche se echo >&2 Something bad happenedper l'output di errore dagli script della shell. Ma >out <in catè solo offuscamento

2
Come potrebbe sort file >fileessere realizzato correttamente?
seth10

11
@setht With sort -o file file.
Kusalananda

6
Bella risposta. Nota che l'ordine conta. < file1 > file2 catsarebbe meglio di > file2 < file1 catquello che eviterebbe di file2essere troncato se file1non fosse possibile aprirlo.
Stéphane Chazelas,

3
Qualcosa da tenere presente: quando si collega a POSIX con frammenti HTML, è meglio specificare l'edizione esatta (come pubs.opengroup.org/onlinepubs/9699919799.2016edition ) poiché i frammenti sono noti per cambiare tra le edizioni di una stessa revisione della specifica (molti link nelle risposte su questo sito, incluso il mio, sono ora sbagliati poiché i frammenti puntano nel posto sbagliato dopo che è stata rilasciata l'edizione 2016).
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.