Nikdy jsem ve skutečnosti nepřemýšlel o tom, jak shell skutečně provádí rourkované příkazy. Vždy mi říkali, že „stdout jednoho programu se provádí do stdin jiného“, jako způsob uvažování o potrubí. Přirozeně jsem si myslel, že v případě řekněme A | B , A se spustí jako první, potom B získá stdout z A a používá stdout z A jako jeho vstup.
Ale všiml jsem si, že když lidé hledají konkrétní proces v ps , budou zahrnovat grep -v "grep" na konci příkazu, abyste se ujistili, že grep se neobjeví v konečném výstupu.
To znamená, že v příkazu ps aux | grep "bash" | grep -v "grep" předpokládá se, že ps věděl, že grep byl spuštěn, a proto je ve výstupu ps . Ale pokud ps dokončí běh, než se jeho výstup přenese do grep , jak to vědělo, že grep běžel?
[email protected]: ~$ ps | grep ".*"
PID TTY TIME CMD
3773 pts/0 00:00:00 bash
3784 pts/0 00:00:00 ps
3785 pts/0 00:00:00 grep
Přijatá odpověď:
Propojené příkazy běží souběžně. Když spustíte ps | grep … , je to štěstí při losování (nebo otázka detailů fungování shellu v kombinaci s doladěním plánovače hluboko v útrobách jádra), zda ps nebo grep se spouští jako první a v každém případě pokračují v souběžném provádění.
To se velmi běžně používá k tomu, aby druhý program mohl zpracovávat data tak, jak vycházejí z prvního programu, než první program dokončí svou činnost. Například
grep pattern very-large-file | tr a-z A-Z
začne zobrazovat odpovídající řádky velkými písmeny ještě před grep dokončil procházení velkého souboru.
grep pattern very-large-file | head -n 1
zobrazí první odpovídající řádek a může se zastavit zpracování dlouho před grep dokončil čtení svého vstupního souboru.
Pokud se někde dočtete, že programy z potrubí běží postupně, opusťte tento dokument. Propojené programy běží souběžně a vždy běží.