GNU/Linux >> Znalost Linux >  >> Linux

Vysvětlení:Vstup, výstup a přesměrování chyb v Linuxu

Pokud jste obeznámeni se základními příkazy Linuxu, měli byste se také naučit koncept přesměrování vstupu a výstupu.

Už víte, jak funguje příkaz Linux. Bere vstup a dává vám výstup. Na scéně je zde několik hráčů. Řeknu vám o nich.

Stdin, stdout a stderr

Když spustíte příkaz Linuxu, jsou zde tři datové proudy, které v něm hrají roli:

  • Standardní vstup (stdin) je zdrojem vstupních dat. Standardně je stdin jakýkoli text zadaný z klávesnice. ID streamu je 0.
  • Standardní výstup (stdout) je výsledkem příkazu. Ve výchozím nastavení se zobrazuje na obrazovce. ID streamu je 1.
  • Standardní chyba (stderr) je chybová zpráva (pokud existuje) vytvořená příkazy. Ve výchozím nastavení se na obrazovce zobrazuje také stderr. ID streamu je 2.

Tyto streamy obsahují data ve formě prostého textu v takzvané vyrovnávací paměti.

Představte si to jako proud vody. Potřebujete zdroj vody, například kohoutek. Napojíte na něj trubku a můžete ji buď uložit do kbelíku (spis), nebo zalévat rostliny (vytisknout). V případě potřeby jej můžete také připojit k jinému kohoutku. V podstatě přesměrováváte vodu.

Linux má také tento koncept přesměrování, kde můžete přesměrovat stdin, stdout a stderr z jejich obvyklého umístění na jiný soubor nebo příkaz (nebo dokonce periferní zařízení, jako jsou tiskárny).

Dovolte mi ukázat, jak přesměrování funguje a jak jej můžete použít.

Přesměrování výstupu

První a nejjednodušší formou přesměrování je přesměrování výstupu, také nazývané přesměrování stdout.

Již víte, že standardně se výstup příkazu zobrazuje na obrazovce. Například používám příkaz ls k výpisu všech souborů a toto je výstup, který dostanu:

[email protected]:~$ ls
appstxt  new.txt  static-ip.txt

Pomocí přesměrování výstupu můžete přesměrovat výstup do souboru. Pokud tyto výstupní soubory neexistují, shell jej vytvoří.

command > file

Dovolte mi například uložit výstup příkazu ls do souboru s názvem output.txt:

[email protected]:~$ ls > output.txt

Výstupní soubor je vytvořen předem

Jaký by podle vás měl být obsah tohoto výstupního souboru? Dovolte mi použít příkaz cat, abych vám ukázal překvapení:

[email protected]:~$ cat output.txt 
appstxt
new.txt
output.txt
static-ip.txt

Všimli jste si, že tam byl zahrnut soubor output.txt ? Tento příklad jsem záměrně vybral, abych vám to ukázal.

Výstupní soubor, na který je stdout přesměrován, je vytvořen před spuštěním zamýšleného příkazu. Proč? Protože potřebuje mít připravený výstupní cíl, kam bude výstup odeslán.

Připojit místo clobber

Jedním z často ignorovaných problémů je, že pokud přesměrujete na soubor, který již existuje, shell soubor nejprve vymaže (vymaže). To znamená, že stávající obsah výstupního souboru bude odstraněn a nahrazen výstupem příkazu.

Místo přepisování jej můžete připojit pomocí>> syntaxe přesměrování.

command >> file

Tip :Clobbling v aktuální relaci shellu můžete zakázat pomocí:set -C

Proč byste přesměrovali stdout? Výstup můžete uložit pro budoucí použití a analyzovat jej později. To je zvláště užitečné, když je výstup příkazu příliš velký a zabírá celou obrazovku. Je to jako shromažďování protokolů.

Přesměrování potrubí

Než uvidíte přesměrování stdin, měli byste se dozvědět o přesměrování potrubí. Toto je běžnější a pravděpodobně to budete často používat.

Pomocí přesměrování potrubí odešlete standardní výstup příkazu na standardní vstup jiného příkazu.

command 1 | command 2

Dovolte mi ukázat vám praktický příklad. Řekněme, že chcete spočítat počet viditelných souborů v aktuálním adresáři. Můžete použít ls -1 (je to číslo jedna, ne písmeno L) pro zobrazení souborů v aktuálním adresáři:

[email protected]:~$ ls -1
appstxt
new.txt
output.txt
static-ip.txt

Pravděpodobně již víte, že příkaz wc se používá pro počítání počtu řádků v souboru. Pokud zkombinujete oba tyto příkazy s roura, získáte toto:

[email protected]:~$ ls -1 | wc -l
4

S roura sdílejí oba příkazy stejnou vyrovnávací paměť. Výstup prvního příkazu se uloží do vyrovnávací paměti a stejná vyrovnávací paměť se poté použije jako vstup pro další příkaz.

Uvidíte výsledek posledního příkazu v kanálu. To je zřejmé, protože stdout předchozího příkazu (příkazů) je předán dalším příkazům namísto přechodu na obrazovku.

Přesměrování potrubí nebo potrubí není omezeno na připojení pouze dvou příkazů. Můžete připojit více příkazů, pokud lze výstup jednoho příkazu použít jako vstup příkazu dalšího.

command_1 | command_2 | command_3 | command_4

Pamatujte si, že stdout/stdin je kus dat, nikoli názvy souborů

Někteří noví uživatelé Linuxu jsou při používání přesměrování zmateni. Pokud příkaz vrátí spoustu názvů souborů jako výstup, nemůžete tyto názvy souborů použít jako argument.

Pokud například použijete příkaz find k nalezení všech souborů končících příponou .txt, nemůžete jej předat kanálem a přesunout nalezené soubory do nového adresáře, ne přímo takto:

find . -type f -name "*.txt" | mv destination_directory

To je důvod, proč často uvidíte příkaz find použitý v konjugaci s příkazem exec nebo xargs. Tyto speciální příkazy ‚převedou text se spoustou názvů souborů na název souboru‘, který lze předat jako argument.

find . -type f -name "*.txt" | xargs -t -I{} mv {} ../new_dir

Přesměrování vstupu

Přesměrování stdin můžete použít k předání obsahu textového souboru příkazu, jako je tento:

command < file

Neuvidíte, že by se stdin hodně používal. Je to proto, že většina linuxových příkazů přijímá názvy souborů jako argument, a proto často není vyžadováno přesměrování stdin.

Vezměte si například toto:

head < filename.txt

Výše uvedený příkaz mohl být právě head filename.txt (bez <).

Není to tak, že by přesměrování stdin bylo úplně zbytečné. Některé příkazy na to spoléhají. Vezměte si například příkaz tr. Tento příkaz toho umí hodně, ale v příkladu níže převede vstupní text z malých na velká písmena:

tr a-z A-Z < filename.txt

Ve skutečnosti se použití stdin doporučuje speciálně přes potrubí, aby se zabránilo zbytečnému použití příkazu cat.

Mnoho lidí by například použilo výše uvedený příklad s cat a pak na něm použili tr. Upřímně řečeno, zde není potřeba používat kočku.

cat filename.txt | tr a-z A-Z

Kombinovat přesměrování

Můžete kombinovat stdin, stdout a přesměrování potrubí podle vašich potřeb.

Například níže uvedený příkaz vypíše všechny soubory .txt v aktuálním adresáři a poté provede počet těchto souborů .txt a uloží výstup do nového souboru.

ls *.txt | wc -l > count.txt

Chyba přesměrování

Někdy, když spustíte nějaký příkaz nebo skript, uvidíte, že se na obrazovce zobrazí chybová zpráva.

[email protected]:~$ ls -l ffffff > output.txt
ls: cannot access 'ffffff': No such file or directory

Na začátku tohoto článku jsem zmínil, že existují tři datové toky a stderr je jeden z výstupních datových toků, který se ve výchozím nastavení zobrazuje na obrazovce.

Můžete také přesměrovat stderr. Protože se jedná o výstupní datový tok, můžete použít stejný symbol> nebo>> přesměrování, který jste použili pro standardní přesměrování.

Ale jak rozlišíte mezi stdout a stderr, když jsou oba výstupní datový tok? Podle jejich ID streamu (také nazývaného deskriptor souboru).

Datový stream ID streamu
stdin 0
stdout 1
stderr 2
-t, –seznam
-u, –aktualizace
-x, –extrahovat, –get
-j, –bzip2
-z, –gzip, –gunzip, –ungzip

Ve výchozím nastavení, když použijete symbol přesměrování výstupu>, ve skutečnosti to znamená 1>. Řečeno slovy, říkáte, že se zde odebírá datový tok s ID 1.

Když musíte přesměrovat stderr, použijete jeho ID jako 2> nebo 2>>. To znamená, že přesměrování výstupu je pro datový tok stderr (ID 2).

Příklady přesměrování Stderr

Dovolte mi, abych vám to ukázal na několika příkladech. Předpokládejme, že chcete pouze uložit chybu, můžete použít něco takového:

[email protected]:~$ ls fffff 2> error.txt
[email protected]:~$ cat error.txt 
ls: cannot access 'fffff': No such file or directory

To bylo jednoduché. Udělejme to trochu složitější (a užitečnější):

[email protected]:~$ ls -l new.txt ffff > output.txt 2> error.txt 
[email protected]:~$ cat output.txt 
-rw-rw-r-- 1 abhishek abhishek 0 May  5 10:25 new.txt
[email protected]:~$ cat error.txt 
ls: cannot access 'ffff': No such file or directory

Ve výše uvedeném příkladu se příkaz ls pokouší zobrazit dva soubory. U jednoho souboru je to úspěšné a u druhého chyba. Takže jsem zde přesměroval stdout na ouput.txt (s>) a stderr na error.txt (s 2>).

Můžete také přesměrovat stdout i stderr do stejného souboru. Existují způsoby, jak to udělat.

V níže uvedeném příkladu nejprve posílám stderr (s 2>>) do souboru combined.txt v režimu připojení. A pak je stdout (s>>) odeslán do stejného souboru v režimu připojení.

[email protected]:~$ ls -l new.txt fff 2>> combined.txt >> combined.txt 
[email protected]:~$ cat combined.txt 
ls: cannot access 'fff': No such file or directory
-rw-rw-r-- 1 abhishek abhishek 0 May  5 10:25 new.txt

Dalším způsobem, a to je preferovaný, je použít něco jako 2>&1. Což lze zhruba přeložit jako „přesměrování stderr na stejnou adresu jako stdout“.

Vezměme si předchozí příklad a tentokrát použijte 2>&1 k přesměrování stdout i stderr do stejného souboru.

[email protected]:~$ ls -l new.txt fff > output.txt 2>&1
[email protected]:~$ cat output.txt 
ls: cannot access 'fff': No such file or directory
-rw-rw-r-- 1 abhishek abhishek 0 May  5 10:25 new.txt

Mějte na paměti, že nemůžete použít 2>>&1, abyste jej použili v režimu připojení. 2>&1 již přejde do režimu připojení.

Můžete také použít nejprve 2> a poté použít 1>&2 k přesměrování stdout do stejného souboru jako stderr. V podstatě je to „>&“, které přesměrovává jeden datový tok na jiný.

Přehled

  • Existují tři datové toky. Jeden vstupní, stdin (0) a dva výstupní datové toky stdout (1) a stderr (2).
  • Klávesnice je výchozí standardní zařízení a obrazovka je výchozí výstupní zařízení.
  • Přesměrování výstupu se používá s> nebo>> (pro režim připojení).
  • Přesměrování vstupu se používá s <.
  • Stderr lze přesměrovat pomocí 2> nebo 2>>.
  • Stderr a stdout lze kombinovat pomocí 2>&1.

Protože se učíte o přesměrování, měli byste také vědět o příkazu tee. Tento příkaz umožňuje současné zobrazení na standardní výstup a uložení do souboru.

Doufám, že se vám tento podrobný průvodce o přesměrování v Linuxu líbil. Pokud máte stále pochybnosti nebo máte návrhy na vylepšení tohoto článku, dejte mi prosím vědět v sekci komentářů.


Linux
  1. Příkaz historie v Linuxu Vysvětleno do hloubky

  2. Linuxové příkazy:jobs, bg a fg

  3. Přesměrování vstupu/výstupu v Linuxu/Unixu

  1. $_ vs! $. Poslední argument předchozího příkazu a přesměrování výstupu?

  2. Příkaz ls v Linuxu:17 vysvětlení užitečných příkladů

  3. Pipes a přesměrování v Linuxu – vysvětleno!

  1. Práce s Input Output a přesměrováním chyb v Linuxu

  2. Vysvětlení příkazu tar pro Linux

  3. Jak interpretovat a opravit chybu vstupu/výstupu v Linuxu?