GNU/Linux >> Znalost Linux >  >> Linux

Snažíte se pochopit syntaxe přesměrování Bash a jejich výstupy?

Jsem v Linuxu nováčkem a snažím se pochopit, jak fungují přesměrování.

Testoval jsem různé syntaxe pro přesměrování stdout a stderr do stejného souboru, které nedávají všechny stejné výsledky.

Pokud se například pokusím vypsat 2 soubory, které neexistují (file1 a file2 ) a 2, které ano (foo a fz ):

Syntaxe č. 1 (bez přesměrování):

$ ls file1 foo fz file2

Zde je výstup, který dostanu do terminálu:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo  fz

Syntaxe č. 2:

Nyní s přesměrováním:

$ ls file1 foo fz file2 > redirect 2>&1

redirect soubor obsahuje totéž jako výsledek pro syntaxi #1:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

S oběma výše uvedenými syntaxemi se tedy zdá, že shell vypíše stderr nejprve, potom stdout .

Syntaxe č. 3:

Nyní, když to zkusím s některou z následujících syntaxí:

$ ls file1 foo fz file2 > redirect 2> redirect

nebo

$ ls file1 foo fz file2 2> redirect > redirect

Poté redirect soubor bude obsahovat toto:

foo
fz
nnot access file1: No such file or directory
ls: cannot access file2: No such file or directory

Tady to vypadá jako stdout je vytištěno před stderr , ale pak vidíme, že začátek stderr je „oříznuto“ o stejný počet znaků jako stdout .

stdout má 6 znaků (foo fz , včetně návratu vozíku), tedy prvních 6 znaků z stderr (ls: ca ) byly přepsány stdout .
Takže to vlastně vypadá jako stderr byl vytištěn jako první, a to stdout byl poté vytištěn přes stderr místo toho, aby k němu byl připojen.

Větší smysl by mi však dávalo, kdyby stderr byl úplně smazáno a nahrazeno stdout , spíše než jen částečně přepsaný.

Syntaxe č. 4:

Jediný způsob, jak jsem našel, jak opravit syntaxi #3, je přidání operátoru append do stdout :

$ ls file1 foo fz file2 >> redirect 2> redirect

nebo

$ ls file1 foo fz file2 2> redirect >> redirect

Což vytváří totéž jako syntaxe #2:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

Tento článek vysvětluje, že syntaxe #3 je chybná (pravděpodobně i syntaxe #4). Ale pro argumentaci:proč je syntaxe #3 špatná? Co přesně říká (nebo ne telling) shell dělat na rozdíl od syntaxe #2?

Související:Jaký je rozdíl mezi $(…) a `…` v Bash?

Existuje také důvod, proč se na výstupu vždy zobrazuje stderr před stdout ?

Děkuji!

Přijatá odpověď:

Je to jako spouštění dvou procesů pro zápis do stejného souboru současně… špatný nápad. Skončíte se dvěma různými popisovači otevřených souborů a vaše data mohou být zkomolená (jak je tomu v bodě 3 výše). Použití syntaxe #2 je správné; to dělá jednu popisovač souboru a ukazuje stderr i stdout na stejné místo.

Pokud jde o stderr, který se vždy tiskne jako první, neexistuje na to žádné pravidlo. Mám podezření, že s ls je to proto, že ls potřebuje zkontrolovat každý záznam v adresáři, než může skutečně uvést, že konkrétní soubor neexistuje. Takže místo toho, aby provedl N průchodů přes adresářovou tabulku, provede jeden průchod, zkontroluje všechny zadané argumenty příkazového řádku, nahlásí chyby a vytiskne nalezené soubory. Jiné příkazy se mohou tisknout do stderr po stdout nebo je dokonce střídat.


Linux
  1. Linuxové scénáře v reálném čase a problémy s jejich řešeními

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

  3. Jak zajistit, aby příkaz alias fungoval ve skriptu bash nebo souboru bashrc

  1. najít a zkopírovat soubor pomocí Bash

  2. Extrahujte základní název souboru bez cesty a přípony v bash

  3. Při pokusu o použití bash v systému Windows se neobjevila žádná zpráva o instalaci distribuce

  1. Jak zajistit, aby byly soubory a adresáře neodstranitelné, a to i přes kořen v Linuxu

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

  3. Jak provést třídění ls podle přípony souboru a poté názvu?