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
dir2ed 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