В чем разница между "&> foo" и "> foo 2> & 1"?

Кажется, есть две идиомы bash для перенаправления STDOUT и STDERR в файл:

fooscript &> foo

... и ...

fooscript > foo 2>&1

Какая разница? Мне кажется, что первый - это просто ярлык для второго, но мой коллега утверждает, что второй не выдаст никаких результатов, даже если есть ошибка с начальным перенаправлением, тогда как первый будет выдавать ошибки перенаправления в STDOUT.

РЕДАКТИРОВАТЬ: Хорошо ... похоже, люди не понимают, о чем я спрашиваю, поэтому я постараюсь уточнить:

Может ли кто-нибудь привести мне пример, в котором две строки конкретные строки, написанные выше, приведут к разному поведению?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
0
2 421
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

&> foo # Will take all and redirect all output to foo.

2>&1 # will redirect stderr to stdout.

Спасибо, но я спрашивал о разнице между "> foo 2> & 1" и "&> foo", а не "2> & 1 foo" и "&> foo".

Max Cantor 09.10.2008 21:06

Сначала весь вывод идет в foo. Во втором сценарии fooscript отправляет stdout в foo, а затем foo отправляет stderr в stdout и печатает везде, где когда-либо указывается stdout. (обычно консоль)

J.J. 09.10.2008 21:16

Да, но в чем разница между этими двумя вещами? Есть один? Вы можете привести пример ситуации, когда они будут вести себя по-разному?

Max Cantor 09.10.2008 21:20

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, добавленные в файл журнала.

Ответ принят как подходящий

Из руководство по bash:

There are two formats for redirecting standard output and standard error:

&>word

and

>&word

Of 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, произойдет то, что вы описали.

ephemient 09.10.2008 22:50

Вы правы, вывод fooscript не перенаправляется в fooscript &> foo. Вместо этого пустая команда перенаправляется в файл foo. Я отредактировал свой ответ, чтобы сказать это.

Jouni K. Seppänen 13.10.2008 19:52

Я знаю, что это довольно старая публикация ... но поделюсь тем, что может ответить на вопрос: * ..приведет к другому поведению?

Сценарий: Когда вы пытаетесь использовать «тройник» и хотите сохранить код выхода, используя подстановку процесса в bash ... someScript.sh 2> & 1> (tee "toALog") # это не может записать вывод, помещенный в журнал

тогда как :

someScript.sh> &> (tee "toALog") # отлично работает!

Другие вопросы по теме