La tua domanda è strettamente correlata al modo in cui la shell che stai utilizzando analizza l'input dell'utente sulla riga di comando.
Se la prima parola nella riga di comando è un programma, situato in una cartella speciale (definita principalmente da PATH
) e non vengono dati più caratteri speciali (dipende dalla shell che si sta utilizzando), tutte le parole successive separate da spazi o tab vengono passate a il programma in una forma speciale, cioè un array. Con ogni parola come un elemento nell'array.
Come il programma, che si intende invocare, interpreta gli argomenti (situati nella matrice) dipende da come è programmato. Ci sono alcuni quasi standard su come dovrebbe apparire la sintassi degli argomenti, ma in generale il programmatore è completamente libero. Quindi il primo argomento può essere interpretato come il nome di un file o qualunque cosa il programmatore pensi al momento in cui ha scritto il programma.
Nel caso in cui si aggiunga il carattere speciale <
o >
alla riga di comando, la shell non aggiunge <
e >
né le parole successive all'array che verrà passato al programma. Con <
o >
dato la shell inizia a fare cose fantasiose, supportate dal kernel sottostante ( piping parole chiave ). Per comprendere quello che sta succedendo è necessario capire che cosa STDIN
e STDOUT
(poiché non è immediatamente legato i tralascio STDERR
) sono.
Tutto ciò che vedi sul tuo terminale (nella maggior parte dei casi una parte del tuo display) è scritto dalla shell o da qualsiasi altro programma che hai invocato in precedenza in un file speciale (in unix tutto è un file ). Questo file ha un ID speciale e viene chiamato STDOUT
. Se un programma vuole leggere i dati dalla tastiera, non esegue il polling della tastiera direttamente (almeno nella maggior parte dei casi) ma legge da un file speciale chiamato STDIN
. Internamente questo file è collegato al dispositivo di input standard, nella maggior parte dei casi alla tastiera.
Se la shell legge <
o >
in una riga di comando analizzata, manipola STDIN
o STDOUT
in un tipo particolare per il tempo in cui il programma corrispondente è in esecuzione. STDIN
e STDOUT
non puntano più al terminale o al dispositivo di input standard ma piuttosto al nome del file successivo sulla riga di comando.
Nel caso delle due linee
cat file_name
cat < file_name
il comportamento osservato è identico perché lo sviluppatore corrispondente fa cat
leggere STDIN
o leggere i dati dal file, il cui nome è dato come primo argomento della riga di comando (che è il primo elemento dell'array a cui passa la shell cat
). Successivamente cat
scrive l'intero contenuto di file_name
o STDIN
sul terminale poiché non istruiamo la shell a manipolare STDOUT
. Ricorda che nella seconda riga la tua shell manipola STDIN
in questo modo, che non punta più al tuo dispositivo di input standard ma punta a un file chiamato file_name
nella tua directory di lavoro corrente.
Nell'altro caso della linea
man < file_name
man
non ha lo scopo di leggere nulla STDIN
se viene chiamato senza argomenti, ad esempio un array vuoto. Quindi la linea
man < file_name
è uguale a
man
Ad esempio man
leggerà qualcosa da STDIN
anche se passi -l -
a man
. Con questa opzione fornita nella riga di comando è possibile visualizzare il contenuto di tutto ciò che viene man
letto STDIN
sul terminale. Così
man -l - < file_name
funzionerebbe anche (ma attenzione man
non è solo un cercapersone ma analizza anche l'input del file e quindi il contenuto del file e il contenuto visualizzato potrebbero differire).
Quindi STDIN
, come STDOUT
e gli argomenti della riga di comando vengono interpretati dipende tutto dallo sviluppatore corrispondente.
Spero che la mia risposta possa chiarire le cose.
man -l - < file_name
per rendere gliman
interpretiSTDIN
come argomenti, ma non riesce nel mio sistema conSTDERR
:man -l - < tee man: invalid option -- l man, version 1.6c