Jak přesměrovat stderr do souboru [duplicitně]

166

Při použití příkazu nohup k zadání příkazu k běhu na pozadí se některý obsah zobrazí v terminálu.

cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

Chci tento obsah uložit do souboru.

    
dané André M. Faria 18.05.2015 14:31

2 odpovědi

270

Existují dva hlavní výstupní toky v systému Linux (a dalších operačních systémech), standardní výstup (stdout) a standardní chyba (stderr). Chybové zprávy, jako ty, které zobrazujete, jsou vytištěny na standardní chybu. Klasický operátor přesměrování (command > file) pouze přesměruje standardní výstup, takže standardní chyba je stále zobrazena na terminálu. Chcete-li také stderr přesměrovat, máte několik možností:

  1. Přesměrování stdout na jeden soubor a stderr do jiného souboru:

    command > out 2>error
    
  2. Přesměrování stderr na stdout (&1) a přesměrování stdru do souboru:

    command >out 2>&1
    
  3. Přesměrování obou souborů:

    command &> out
    

Další informace o různých operátorech řízení a přesměrování naleznete v zde .

    
odpověděl terdon 18.05.2015 14:50
6

Nejprve je třeba poznamenat, že existuje několik způsobů, které závisí na vašem účelu a prostředí, a proto to vyžaduje nepatrné pochopení několika aspektů. Nejvíce typické je pomocí2> v shellů typu Bourne , například dash (který je propojen s/bin/sh) abash; první je implicitní a POSIX kompatibilní shell a druhý je to, co většina uživatelů používá pro interaktivní relaci. Liší se v syntaxi a funkcích, ale naštěstí pro nás přesměrování streamu chyb funguje stejně (s výjimkou&> nestandardního). V případě csh a jeho derivátů, přesměrování stderr v tom docela nefunguje.

Vrátíme se k2> části. Dvě důležité věci si všimněte:> znamená operátor přesměrování, kde otevřeme soubor a2 integer znamená deskriptor souboru stderr; ve skutečnosti je přesně tak, jak standard POSIX pro shell definuje přesměrování v části 2.7 :

[n]redir-op word

Pro jednoduché přesměrování> je1 integer implikováno prostdout, tj.echo Hello World > /dev/null je stejné jakoecho Hello World 1>/dev/null. Všimněte si, že celočíselný operátor nebo operátor přesměrování nelze citovat, jinak shell je nerozpozná jako takový a místo toho se chová jako doslovný řetězec textu. Co se týče rozestupu, je důležité, aby celé číslo bylo vedle operátoru přesměrování, ale soubor může být buď vedle operátora přesměrování, nebo ne, tj.% Co_kde% acommand 2>/dev/null bude pracovat správně.

Trochu zjednodušená syntaxe pro typický příkaz shell by byla

 command [arg1] [arg2]  2> /dev/null

Zde je trik, že přesměrování se může objevit kdekoli. To platí jak procommand 2> /dev/null, tak pro2> command [arg1]. Všimněte si, že procommand 2> [arg1] shellu existujebash způsob, jak přesměrovat oba stdout a stderr proudy najednou současně, ale znovu - je to bash specifické a pokud se snažíte o přenositelnost skriptů, nemusí fungovat. Viz také Ubuntu Wiki a Jaký je rozdíl mezi & > a 2 & 1 .

Poznámka: Operátor přesměrování&> zkrátí soubor a přepsá jej, pokud soubor existuje. % Co_kde% může být použito pro přidání> do souboru.

Pokud si všimnete,2>> je určen pro jeden příkaz. Pro skripty můžeme přesměrovat stderr stream celého skriptu zvenčí jako vstderr, nebo můžeme využít exec vestavěného . Vestavěný příkaz exec má možnost přetočit tok pro celou schůzku shell, abych tak řekl, ať interactivně nebo skriptem. Něco jako

#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file

V tomto příkladu by měl protokolovat soubor>.

Ještě jiný způsob je prostřednictvím funkcí. Když kopciuszek uvedl ve své odpovědi, můžeme napsat prohlášení o funkci s již připojeným přesměrováním, což je

some_function(){
    command1
    command2
} 2> my_log_file.txt
    
odpověděl Sergiy Kolodyazhnyy 03.05.2018 09:48