Stai confondendo argomenti e input standard. Inviare dati a un programma non equivale a fornirgli argomenti da riga di comando.
Nel tuo primo caso, non stai passando argomenti al tuo script, ma solo alimentando i dati attraverso il suo flusso di input standard. Quindi $1
non è impostato per l'intera durata dello script.
La prima invocazione di more
quindi non ha parametri e impagina lo standard input. Questo mostra ciò che avevi reindirizzato lì (dir1
, come testo). Il successivo echo
stampa solo una nuova riga poiché non ottiene nulla da stampare e l'ultimo more
non ha più niente da stampare - l'input standard è stato "prosciugato" dal primo.
Nel secondo caso, passi un argomento. Quindi $1
ha il valore dir2
nella sceneggiatura. Succede la stessa cosa, tranne per il primo more
entrambi:
- pagine attraverso entrambi gli input standard
- tenta di impaginare il file
dir2
ed errori poiché quella è una directory
L'eco fa quello che ci si aspetta dato che $1
contiene dir2
e l'ultimo more
solo errori su dir2
- non ha nulla da leggere dallo standard input.
La differenza sta negli "Argomenti " VS "Immissione standard ".
Quando esegui echo dir1 | bash script.sh
, il $1
argomento nel tuo script.sh
è sempre vuoto in quanto non viene fornito alcun argomento (prova ad aggiungere un set -x
all'inizio e lo vedrai nell'output di debug). Il dir1
che viene ripetuto proviene dallo input standard come more
comando read stdin se non viene fornito alcun argomento (ricorda $1
è vuoto).
Come cmd1 | cmd2
funziona
Quando si utilizza pipe :
cmd2
è un sottoprocesso dicmd1
.- lo stdin di
cmd2
è "collegato" sullo stdout dicmd1
.
Poiché linux stdio lib offriva un flusso bufferizzato attraverso il descrittore di file, il contenuto di stdin verrà consumato (ovvero letto solo una volta) solo quando stdin verrà aperto .
Passo dopo passo cmd1 | cmd2
flusso di lavoro
Esempio di comando :
echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")
echo dir1 |
:scrivi "dir1\n
" sullo stdout del primo comando che non viene ripetuto ma memorizzato nel buffer tramite stdio e disponibile per il sottoprocesso tramite stdin.echo "a"
:scrivi "a\n
" su stdout; non legge stdin ! quindi il "dir1\n
" la stringa è ancora disponibileread stdinvalue
:legge stdin fino a EOL (o EOF) e memorizza la stringa in una variabile bashecho "$stdinvalue"
:scrive il valore della variabile stdinvalue in stdout