Кажется, есть две идиомы bash для перенаправления STDOUT и STDERR в файл:
fooscript &> foo
... и ...
fooscript > foo 2>&1
Какая разница? Мне кажется, что первый - это просто ярлык для второго, но мой коллега утверждает, что второй не выдаст никаких результатов, даже если есть ошибка с начальным перенаправлением, тогда как первый будет выдавать ошибки перенаправления в STDOUT.
РЕДАКТИРОВАТЬ: Хорошо ... похоже, люди не понимают, о чем я спрашиваю, поэтому я постараюсь уточнить:
Может ли кто-нибудь привести мне пример, в котором две строки конкретные строки, написанные выше, приведут к разному поведению?





&> foo # Will take all and redirect all output to foo.
2>&1 # will redirect stderr to stdout.
Сначала весь вывод идет в foo. Во втором сценарии fooscript отправляет stdout в foo, а затем foo отправляет stderr в stdout и печатает везде, где когда-либо указывается stdout. (обычно консоль)
Да, но в чем разница между этими двумя вещами? Есть один? Вы можете привести пример ситуации, когда они будут вести себя по-разному?
2>&1 может быть полезен в случаях, когда вы не перенаправляете stdout куда-то еще, а просто хотите, чтобы stderr отправлялся в то же место (например, консоль), что и stdout (возможно, если команда, которую вы выполняете, уже отправляет stderr в другом месте, кроме консоли).
2> & 1 зависит от порядка, в котором он указан в командной строке. Где &> отправляет и stdout, и stderr куда угодно, 2> & 1 отправляет stderr туда, где stdout - это В данный момент, идущий в этот момент в командной строке. Таким образом:
команда> файл 2> & 1
отличается от:
команда 2> & 1> файл
где первый перенаправляет как stdout, так и stderr в файл, последний перенаправляет stderr туда, где идет stdout, прежде чем он будет перенаправлен в файл (в данном случае, вероятно, терминал). Это полезно, если вы хотите сделать что-то вроде:
команда 2> & 1> файл | меньше
Если вы хотите использовать less для пролистывания вывода stderr и сохранения вывода stdout в файл.
&>foo меньше печатает, чем >foo 2>&1, и менее подвержен ошибкам (вы не можете получить их в неправильном порядке), но дает тот же результат.
2>&1 сбивает с толку, потому что вам нужно поместить его после перенаправления 1>, если stdout не перенаправляется на канал |, и в этом случае он идет до ...
$ some-command 2>&1 >foo # does the unexpected $ some-command >foo 2>&1 # does the same as $ some-command &>foo # this and $ some-command >&foo # compatible with other shells, but trouble if the filename is numeric $ some-command 2>&1 | less # but the redirect goes *before* the pipe here...
По моему опыту, основная причина использования 2>&1 - это когда вы хотите добавить весь вывод в файл, а не перезаписывать файл. С синтаксисом &> вы не можете добавлять. Таким образом, с помощью 2>&1 вы можете написать что-то вроде program >> alloutput.log 2>&1 и получить выходные данные stdout и stderr, добавленные в файл журнала.
There are two formats for redirecting standard output and standard error:
&>wordand
>&wordOf the two forms, the first is preferred. This is semantically equivalent to
>word 2>&1
Фраза «семантически эквивалентная» должна разрешить проблему с вашим коллегой.
Ситуация, когда две строки имеют разное поведение, - это когда ваш скрипт запущен не в bash, а в какой-то более простой оболочке из семейства sh, например бросаться (который, как мне кажется, используется как / bin / sh в некоторых дистрибутивах Linux, потому что он более легкий, чем bash). В этом случае,
fooscript &> foo
интерпретируется как две команды: первая запускает fooscript в фоновом режиме, а вторая усекает файл foo. Команда
fooscript > foo 2>&1
запускает fooscript на переднем плане и перенаправляет его вывод и стандартную ошибку в файл foo. В bash я думаю, что строки всегда будут делать одно и то же.
На самом деле это не то, что делает &> в тире - он запускает fooscript в фоновом режиме, но ничего не перенаправляется. Если бы вы написали (fooscript &)> foo, произойдет то, что вы описали.
Вы правы, вывод fooscript не перенаправляется в fooscript &> foo. Вместо этого пустая команда перенаправляется в файл foo. Я отредактировал свой ответ, чтобы сказать это.
Я знаю, что это довольно старая публикация ... но поделюсь тем, что может ответить на вопрос: * ..приведет к другому поведению?
Сценарий: Когда вы пытаетесь использовать «тройник» и хотите сохранить код выхода, используя подстановку процесса в bash ... someScript.sh 2> & 1> (tee "toALog") # это не может записать вывод, помещенный в журнал
тогда как :
someScript.sh> &> (tee "toALog") # отлично работает!
Спасибо, но я спрашивал о разнице между "> foo 2> & 1" и "&> foo", а не "2> & 1 foo" и "&> foo".