Pletete si argumenty a standardní vstupy. Přepojování dat do programu není ekvivalentní tomu, když mu dáváte argumenty příkazového řádku.
V prvním případě svému skriptu nepředáváte žádné argumenty, pouze mu dodáváte data prostřednictvím standardního vstupního proudu. Takže $1
není nastaveno po celou dobu trvání skriptu.
První vyvolání more
nemá tedy žádný parametr a stránkuje standardní vstup. Zobrazí se, co jste tam vložili (dir1
, jako text). Následující echo
vytiskne pouze nový řádek, protože nedostane nic k tisku, a poslední more
už také nemá co tisknout - standardní vstup byl "vypuštěn" prvním.
Ve druhém případě předáte argument. Takže $1
má hodnotu dir2
ve scénáři. Stane se to samé, až na to, že první more
oba:
- stránky přes oba standardní vstupy
- pokusí se o stránkování souboru
dir2
a chyby, protože se jedná o adresář
Echo dělá to, co se očekává vzhledem k $1
obsahuje dir2
a poslední more
pouze chyby na dir2
- nemá co číst ze standardního vstupu.
Rozdíl je v „Argumenty " VS "Standardní vstup ".
."
Když spustíte echo dir1 | bash script.sh
, $1
argument ve vašem script.sh
je vždy prázdný, protože k němu není uveden žádný argument (zkuste přidat set -x
na začátku a uvidíte to ve výstupu ladění). dir1
který je echován pochází ze standardního vstupu jako more
příkaz read stdin, pokud není zadán žádný argument (pamatujte na $1
je prázdný).
Jak cmd1 | cmd2
funguje
Při použití potrubí :
cmd2
je podprocesemcmd1
.- Stdin
cmd2
je "zapojeno" na stdout zcmd1
.
Protože linux stdio lib nabízel proud s vyrovnávací pamětí prostřednictvím deskriptoru souboru, obsah stdin bude spotřebován (tj. pouze jednou pro čtení) pouze při otevření stdin .
Krok za krokem cmd1 | cmd2
pracovní postup
Příklad příkazu :
echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")
echo dir1 |
:napište "dir1\n
" na stdout prvního příkazu, který není echoován, ale ukládá se do vyrovnávací paměti přes stdio a je dostupný pro podproces přes stdin.echo "a"
:napište "a\n
" na stdout; nečte stdin ! takže "dir1\n
" řetězec je stále k dispoziciread stdinvalue
:číst stdin až do EOL (nebo EOF) a uložit řetězec do proměnné bashecho "$stdinvalue"
:zapsat hodnotu proměnné stdinvalue do stdout