Jak przekierować i dołączyć stdout i stderr do pliku z Bash?

Aby przekierować stdout do okrojonego pliku w bashu, wiem, że należy użyć:

cmd > file.txt

Aby przekierować stdout w Bash, dołączając do pliku, wiem, że należy użyć:

cmd >> file.txt

Aby przekierować zarówno stdout i stderr do okrojonego pliku, wiem, że należy użyć:

cmd &> file.txt

Jak przekierować zarówno stdout i stderr do pliku? Nie zadziałało na mnie.

Author: Timur Shtatland, 2009-05-18

7 answers

cmd >>file.txt 2>&1

Bash wykonuje przekierowania od lewej do prawej w następujący sposób:

  1. >>file.txt: Otwórz file.txt w trybie dodawania i przekieruj stdout tam.
  2. 2>&1: przekierowanie stderr do "gdzie stdout obecnie idzie" . W tym przypadku jest to plik otwarty w trybie dopisywania. Innymi słowy, &1 ponownie wykorzystuje deskryptor pliku, którego obecnie używa stdout.
 2109
Author: Alex Martelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 14:55:58

Istnieją dwa sposoby, aby to zrobić, w zależności od wersji Bash.

Klasyczny i przenośny (Bash pre-4 ) sposób to:

cmd >> outfile 2>&1

A nonportable way, starting with Bash 4 is

cmd &>> outfile

(analogicznie do &> outfile)

Dla dobrego stylu kodowania, powinieneś

    [20]}zdecyduj, czy przenośność jest problemem (następnie użyj klasycznego sposobu) {21]} [20]} zdecyduj, czy przenoszenie nawet do Bash pre-4 jest problemem (następnie użyj klasycznego sposobu) {21]}
  • bez względu na składnię, której używasz, nie zmieniać go w ramach tego samego skryptu (zamieszanie!)

Jeśli twój skrypt zaczyna się od #!/bin/sh (bez względu na to, czy jest zamierzony, czy nie), to rozwiązanie Bash 4 i ogólnie dowolny kod specyficzny dla Bash nie jest dobrym rozwiązaniem.

Pamiętaj również, że Bash 4 &>> jest tylko krótszą składnią - nie wprowadza żadnych nowych funkcjonalności ani niczego podobnego.

Składnia jest (obok innych składni przekierowań) opisana tutaj: http://bash-hackers.org/wiki/doku.php/syntax/redirection#appending_redirected_output_and_error_output

 374
Author: TheBonsai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-23 11:24:34

W Bash możesz również jawnie określić przekierowania do różnych plików:

cmd >log.out 2>log_error.out

Dodawanie będzie:

cmd >>log.out 2>>log_error.out
 93
Author: Aaron R.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 15:39:21

W Bash 4 (jak również ZSH 4.3.11):

cmd &>>outfile

Just out of box

 65
Author: A B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-20 08:47:00

To powinno działać dobrze:

your_command 2>&1 | tee -a file.txt

Zapisze wszystkie logi w pliku .txt oraz zrzucić je na terminal.

 56
Author: Pradeep Goswami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 18:35:42

Spróbuj tego

You_command 1>output.log  2>&1

Twoje użycie & > x.file działa w bash4. przepraszam za to: (

Oto kilka dodatkowych wskazówek.

0, 1, 2...9 to deskryptory plików w bash.

0 oznacza stdin, 1 oznacza stdout, 2 oznacza stderror. 3~9 jest zapasowy do innych tymczasowych zastosowań.

Każdy deskryptor pliku może zostać przekierowany do innego deskryptora pliku lub pliku za pomocą operatora > lub >> (append).

Użycie: file_descriptor> > nazwa pliku | &file_descriptor >

Proszę odnieść się do http://www.tldp.org/LDP/abs/html/io-redirection.html

 25
Author: Quintus.Zhou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-10 03:47:29

Dziwi mnie, że od prawie dziesięciu lat nikt jeszcze nie opublikował takiego podejścia: {]}

Jeśli używasz starszych wersji bash, gdzie &>> nie jest dostępna, możesz również zrobić:

(cmd 2>&1) >> file.txt

To generuje subshell, więc jest mniej wydajny niż tradycyjne podejście cmd >> file.txt 2>&1, a w konsekwencji nie będzie działać dla poleceń, które muszą zmodyfikować obecną powłokę (np. cd, pushd), ale takie podejście wydaje mi się bardziej naturalne i zrozumiałe: {]}

  1. Redirect stderr to stdout.
  2. przekierowanie nowego wyjścia przez dodanie do pliku.

Nawiasy usuwają również wszelkie niejasności kolejności, szczególnie jeśli chcesz przekierować stdout i stderr do innego polecenia.

Edytuj: Aby uniknąć uruchamiania podshell, zamiast nawiasów możesz użyć nawiasów klamrowych, aby utworzyć group command:

{ cmd 2>&1; } >> file.txt

(zauważ, że średnik (lub znak nowej linii) jest wymagany do zakończenia polecenia group.)

 11
Author: jamesdlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-28 04:12:44