Pokud byste někomu pomáhali naučit se koncept potrubí na příkazovém řádku, jaký příklad byste použili? Příklad, který skutečně přišel, byl následující:
cat whatever.txt | less
Mám pocit, že to není nejlepší příklad, a to proto, že je tu jen jeden krok. Co je dobré, ale fundované použití |
?
V ideálním případě se v příkladu, který uvedu, použijí programy, které mají výstupy samy o sobě, které lze spustit nezávisle a poté je zobrazit společně.
Projdu vás poněkud komplexním příkladem, založeným na scénáři skutečného života.
Problém
Řekněme, že příkaz conky
přestal reagovat na ploše a chci ho zabít ručně. Trochu znám Unix, takže vím, že musím provést příkaz kill <PID>
. K získání PID mohu použít ps
nebo top
nebo jakýkoli nástroj, který mi poskytla moje distribuce Unix. Ale jak to mohu udělat jedním příkazem?
Odpověď
$ ps aux | grep conky | grep -v grep | awk '{print $2}' | xargs kill
ODMÍTNUTÍ: Tento příkaz funguje pouze v určitých případech. Nekopírujte/nevkládejte jej do terminálu a nezačněte jej používat, mohlo by to zabít procesy neúmyslně. Spíše se učit jak jej postavit.
Jak to funguje
1- ps aux
Tento příkaz zobrazí seznam spuštěných procesů a některé informace o nich. Zajímavou informací je, že ve druhém sloupci vydá PID každého procesu. Tady je výpis z výstupu příkazu na mém poli:
$ ps aux
rahmu 1925 0.0 0.1 129328 6112 ? S 11:55 0:06 tint2
rahmu 1931 0.0 0.3 154992 12108 ? S 11:55 0:00 volumeicon
rahmu 1933 0.1 0.2 134716 9460 ? S 11:55 0:24 parcellite
rahmu 1940 0.0 0.0 30416 3008 ? S 11:55 0:10 xcompmgr -cC -t-5 -l-5 -r4.2 -o.55 -D6
rahmu 1941 0.0 0.2 160336 8928 ? Ss 11:55 0:00 xfce4-power-manager
rahmu 1943 0.0 0.0 32792 1964 ? S 11:55 0:00 /usr/lib/xfconf/xfconfd
rahmu 1945 0.0 0.0 17584 1292 ? S 11:55 0:00 /usr/lib/gamin/gam_server
rahmu 1946 0.0 0.5 203016 19552 ? S 11:55 0:00 python /usr/bin/system-config-printer-applet
rahmu 1947 0.0 0.3 171840 12872 ? S 11:55 0:00 nm-applet --sm-disable
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:38 conky -q
2- grep conky
Zajímám se pouze o jeden proces, takže pomocí grep
najdu položku odpovídající mému programu conky
.
$ ps aux | grep conky
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:39 conky -q
rahmu 3233 0.0 0.0 7592 840 pts/1 S+ 16:55 0:00 grep conky
3- grep -v grep
Jak můžete vidět v kroku 2, příkaz ps
vydá grep conky
proces v jeho seznamu (je to koneckonců běžící proces). Abych jej mohl filtrovat, mohu spustit grep -v grep
. Možnost -v
řekne grep
, aby odpovídal všem řádkům kromě těm, které obsahují vzor.
$ ps aux | grep conky | grep -v grep
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:39 conky -q
Pozn .: Rád bych věděl, jak udělat kroky 2 a 3 v jediném volání grep
.
4- awk '{print $2}'
Nyní, když jsem izoloval svůj cílový proces. Chci načíst jeho PID. Jinými slovy chci načíst druhé slovo výstupu. Naštěstí pro mě většina (všech?) Moderních odvětví poskytne nějakou verzi skriptovacího jazyka awk
, který se diví tabulárními daty. Náš úkol bude stejně snadný jako print $2
.
$ ps aux | grep conky | grep -v grep | awk '{print $2}'
1948
5- xargs kill
Mám PID. Potřebuji pouze předat to kill
. K tomu použiju xargs
.
xargs kill
bude číst ze vstupu (v našem případě z roury), vytvoří příkaz sestávající z kill <items>
(<items>
jsou cokoli, co je čteno ze vstupu), a poté spusťte vytvořený příkaz. V našem případě provede kill 1948
. Mise splněna.
Závěrečná slova
Uvědomte si, že v závislosti na používané unixové verzi se některé programy mohou chovat trochu jinak (například ps
může vydávat PID ve sloupci $ 3). Pokud se vám zdá něco špatného nebo jiného, přečtěte si dokumentaci svého dodavatele (nebo lépe stránky man
). Také buďte opatrní, protože dlouhé potrubí může být nebezpečné. Nepoužívejte žádné předpoklady, zejména pokud používáte příkazy jako kill
nebo rm
. Pokud například existuje jiný uživatel s názvem 'conky' (nebo 'Aconkyous'), můj příkaz může také zabít všechny jeho spuštěné procesy!
Říkám, že buďte opatrní, zejména u dlouhých dýmek. Vždy je lepší to budovat interaktivně, jak jsme to udělali tady, než dělat předpoklady a lítost později.
Moje oblíbená je tato:
youtube-dl $1 -q -o - | ffmpeg -i - $2
stáhne video z dané adresy URL youtube předané uživatelem $1
a vydá jej jako soubor zadaný $2
. Všimněte si, jak je soubor tiše -q
výstup na STDOUT -o -
, piped to ffmpeg a tam bylo použito jako vstup -i -
.
Zejména pro nováčky v Linuxu to může být praktický příklad, proč může být příkazový řádek užitečný a usnadňuje práci než používání nástrojů GUI. Nejsem si jistý, jak dlouho bude trvat stažení videa z youtube a převedení jeho zvuku na mp3. Výše uvedený řádek to dokáže za několik sekund.
Obecné použití (přečteno: způsob, jakým je nejčastěji používám) je, když z nějakého důvodu musím spouštět některá data pomocí několika nástrojů, abych mohl provádět různé úkoly zpracování.
Řekl bych tedy = použití trubek je jako lepidlo k sestavení několika stavebních bloků (různé nástroje UNIX) dohromady. Jak řekl Ulrich, sort
a uniq
je běžná stanza.
V závislosti na publiku, pokud chcete zdůraznit toto použití dýmek, můžete například začít: „hej, tento sylabus obsahuje odkazy na několik zajímavých PDF s dokumenty a přednáškovými poznámkami, ale některé z nich se opakují. nějak to automatizovat? “
Pak byste mohli ukázat, jak lynx --dump --listonly
získá seznam odkazů, jak může grep
filtrovat odkazy končící na .pdf
, jak se colrm
nebo sed
mohlo zbavit čísel lynx
zápisů zanechaných na každé URL, jak by se mohly sort
a uniq
zbavte se duplikátů a konečně jak wget -i -
lze použít k načtení souborů (pomocí --wait
být samozřejmě šetrný k serveru).
Obávám se, že se jedná o složitý příklad. Na druhou stranu to může pomoci ukázat sílu trubek, když ji jen trubíte a necháte Shell, aby to všechno spustilo najednou.
Nakonec se podělím o ten nepořádek, který jsem udělal asi před rokem a půl ...
while read in; do Host "$in"; done < sites.txt | grep -iv "GOOGLE" | grep -E '1\.2\.3\.4|5\.6\.7\.8' | sed -e 's/has\ address\ 216.70.91.72//' | sed -e 's/has\ address\ 94.23.33.92//' | while read sites; do curl -sL -w "%{http_code} %{url_effective}\\n" "$sites" -o /dev/null; done | grep -ivE '4.*|5.*' | sed -e 's/200//' | sed -e 's/HTTP/http/'
To...
To se dalo udělat mnohem lépe pomocí jediného skriptu Python skript, vsadím se).
Nevím přesně o dobrém, ale potrubí potrubím grep
musí být jedním z nejběžnějších způsobů použití, možná následuje wc -l
. (Ano, grep
má málo známé -c
přepínač.)
Další obyčejná stanza je | sort | uniq
, pouze pokud uniq
vyžaduje, aby byl jeho vstup tříděn.
To je první věc, která mě napadla ...
mysqldump
je aplikace konzoly, která odesílá data, schémata a volitelně procedury a funkce k vytažení. Obvykle se přesměruje do souboru pro zálohu.
mysqldump <options> > mydb.dump
To vám poskytne nekomprimovaný skript sql. Chcete-li ušetřit místo, můžete jej komprimovat pomocí bzip2.
bzip2 mydb.dump
Případně můžete udělat obojí v jednom kroku:
mysqldump <options> | bzip2 > mydb.dump.bz2
V tomto příkladu výše je stdout z mysqldump
převeden na bzip2, který má svůj výstup přesměrován do souboru.
Ne, že to potřebujete pro tento příklad, ale:
$ ps aux | grep -v grep | grep conky
... obrácení pořadí greps zachovává zbarvení, ale je mnohem méně efektivní. pravděpodobně na velkých seznamech, na barvě nezáleží.
tato webová stránka také navrhuje:
https://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep
> Johnsyweb odpověděl 21. února v 10:31 > Obvyklý trik je tento: > Ps aux | grep '[t] erminal' > Toto bude odpovídat řádkům obsahujícím terminál, který grep '[t] erminal' nemá! > Funguje také na mnoha příchutích Unixu.
... ale to nebude fungovat, pokud hledáte jedno písmeno (jako proces 'X').
Zde je příklad, který používám ve své práci pro více potrubí v jednom příkazu. To používá gawk k prohledávání MySQL protokolu obecných dotazů ($ OFILE) a k nalezení všech odepřených přihlášení. Potom třídí tento seznam podle názvu, roury v tomto seznamu na uniq, které počítají výskyty, a potom roury třídí naposledy, aby se počítaný seznam třídil číselně ...
gawk '{ for (x=1;x<=NF;x++) if ( $x~"Access" && $(x+4)~".*@.*") print $(x+4)}' $OFILE | sort | uniq -c | sort -n
Potrubí nejlépe fungují s filtry a překladači
find /usr/bin/ | #produce
sed 's:.*/::' | #translate: strip directory part
grep -i '^z' | #filter : select items starting with z
xargs -d '\n' aFinalConsumer #consume
Tímto způsobem mohou data proudit z jednoho programu do dalšího vyrovnávací paměti a v žádném okamžiku nemusí být všechna data v paměti najednou.
Zde je příklad, který jsem použil pro nastavení proměnné DISPLAY, když xauth nebyl možnost ...
export DISPLAY=\`who am i |awk '{print $NF}' | sed 's/[()]//g'`":0.0"
První příkaz získá potřebná data, tj. Název hostitele nebo IP. Druhý příkaz získá právě ta data (poslední pole). Nakonec poslední příkaz odstraní závorky z dat.
cat filename | less
je strašlivé použití potrubí, protože stačí udělat less filename
Zde je příklad jader, které používám každý den (ale může to být i špatný příklad): ls -la | more -c
Odpovědi scott hoffman a njsg jsou lepšími příklady.
spusťte tento v kterémkoli adresáři, který chcete mít tříděnou analýzu velikosti složky (pak přejděte dolů klávesou END):
du -m| sort -n| less
Sortiert nach Ordnergrösse
Příkazové potrubí můžete použít kdekoli, kde máte pocit, že výstup prvního příkazu může být přiváděn jako vstup do dalšího.
Příklady.
příklad kočky txt | grep {some_line} | awk {some_command}
Jednoduše je to koncept, že pokud cítíte, že výstup příkazu, který jste spustili, může být vstupem jiného příkazu, můžete je poslat potrubím.
A co: vyhledávání vzorů a zobrazení posledního nastávajícího vzoru?
Ukazuje, jak používat tail
, sed
a grep
v kontextu potrubí, které lze vytvořit krok za krokem.