Как я могу перенаправить и добавить как stdout, так и stderr в файл с помощью Bash? - PullRequest
1368 голосов
/ 18 мая 2009

Чтобы перенаправить stdout в усеченный файл в Bash, я знаю использовать:

cmd > file.txt

Для перенаправления stdout в Bash, добавление в файл, я знаю, использовать:

cmd >> file.txt

Чтобы перенаправить stdout и stderr в усеченный файл, я знаю, что использовать:

cmd &> file.txt

Как перенаправить stdout и stderr при добавлении в файл? cmd &>> file.txt у меня не сработало.

Ответы [ 7 ]

1781 голосов
/ 18 мая 2009
cmd >>file.txt 2>&1

Bash выполняет перенаправления слева направо следующим образом:

  1. >>file.txt: открыть file.txt в режиме добавления и перенаправить туда stdout.
  2. 2>&1: Перенаправить stderr на ", куда stdout идет в данный момент" . В данном случае это файл, открытый в режиме добавления. Другими словами, &1 повторно использует дескриптор файла, который stdout использует в настоящее время.
331 голосов
/ 18 мая 2009

Есть два способа сделать это, в зависимости от вашей версии Bash.

Классический и портативный ( Bash pre-4 ) способ:

cmd >> outfile 2>&1

Непортативный способ, начиная с Bash 4 -

cmd &>> outfile

(аналог &> outfile)

Для хорошего стиля кодирования вы должны

  • решить, является ли переносимость проблемой (тогда используйте классический способ)
  • решить, является ли переносимость даже в Bash pre-4 проблемой (тогда используйте классический способ)
  • независимо от того, какой синтаксис вы используете, не меняйте его внутри одного и того же скрипта (путаница!)

Если ваш сценарий уже начинается с #!/bin/sh (независимо от того, предназначен он или нет), то решение Bash 4 и вообще любой специфичный для Bash код не годятся.

Также помните, что Bash 4 &>> является просто более коротким синтаксисом - он не вводит никакой новой функциональности или чего-либо подобного.

Синтаксис (помимо другого синтаксиса перенаправления) описан здесь: http://bash -hackers.org / wiki / doku.php / syntax / redirection # appending_redirected_output_and_error_output

82 голосов
/ 24 июля 2013

В Bash вы также можете явно указать свои перенаправления в разные файлы:

cmd >log.out 2>log_error.out

Добавление будет:

cmd >>log.out 2>>log_error.out
61 голосов
/ 27 марта 2012

В Bash 4 (а также в ZSH 4.3.11):

cmd &>>outfile

просто из коробки

42 голосов
/ 12 декабря 2015

Это должно работать нормально:

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

Он будет хранить все журналы в file.txt , а также выводить их на терминал.

23 голосов
/ 10 апреля 2014

Попробуйте это

You_command 1>output.log  2>&1

Ваше использование &> x.file работает в bash4. простите за это: (

Вот несколько дополнительных советов.

0, 1, 2 ... 9 - дескрипторы файлов в bash.

0 обозначает stdin, 1 обозначает stdout, 2 обозначает stderror. 3 ~ 9 является запасным для любого другого временного использования.

Любой дескриптор файла может быть перенаправлен на другой дескриптор файла или файл с помощью оператора > или >> (приложение).

Использование: <<strong> file_descriptor > > <<strong> filename | & file_descriptor >

Пожалуйста, обратитесь к http://www.tldp.org/LDP/abs/html/io-redirection.html

3 голосов
/ 15 февраля 2019

Я удивлен, что за почти десять лет никто еще не опубликовал этот подход:

Если вы используете более старые версии bash, где &>> недоступно, вы также можете сделать:

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

Это порождает подоболочку, поэтому она менее эффективна, чем традиционный подход cmd >> file.txt 2>&1, но этот подход кажется мне более естественным и понятным:

  1. Перенаправить stderr на стандартный вывод.
  2. Перенаправить новый стандартный вывод, добавив в файл.

Кроме того, скобки убирают любую двусмысленность порядка, особенно если вы хотите вместо этого передать stdout и stderr другой команде.

...