Какая разница между "&> foo" и "> foo 2> & 1"?

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

fooscript &> foo

... и...

fooscript > foo 2>&1

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

EDIT: Хорошо... похоже, люди не понимают, что я прошу, поэтому я попытаюсь уточнить:

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

Ответ 1

В bash manual:

Существует два формата для перенаправления стандартного вывода и стандартной ошибки:

&>word

и

>&word

Из двух форм предпочтительным является первое. Это семантически эквивалентно

 >word 2>&1

Фраза "семантически эквивалентная" должна решить проблему с вашим сотрудником.

Ответ 2

Ситуация, когда две строки имеют другое поведение, - это когда ваш script не работает в bash, а какая-то более простая оболочка в семействе sh, например. тире (который, как мне кажется, используется в качестве /bin/sh в некоторых дистрибутивах Linux, потому что он более легкий, чем bash). В этом случае

fooscript &> foo

интерпретируется как две команды: первая запускает fooscript в фоновом режиме, а вторая обрезает файл foo. Команда

fooscript > foo 2>&1

запускает fooscript на переднем плане и перенаправляет свой вывод и стандартную ошибку в файл foo. В bash я думаю, что линии всегда будут делать то же самое.

Ответ 3

Основной причиной использования 2>&1, по моему опыту, является то, что вы хотите добавить весь вывод в файл, а не перезаписывать файл. С синтаксисом &> вы не можете добавлять. Таким образом, с помощью 2>&1 вы можете написать что-то вроде program >> alloutput.log 2>&1 и получить вывод stdout и stderr в файл журнала.

Ответ 4

&>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...

Ответ 5

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

2>&1 # will redirect stderr to stdout.

Ответ 6

2 > & 1 зависит от того, в каком порядке он указан в командной строке. Где & > отправляет как stdout, так и stderr туда, где, 2 > & 1 отправляет stderr туда, где stdout в настоящее время собирается в этой точке в командной строке. Таким образом:

command > file 2 > & 1

отличается от:

команда 2 > & 1 > файл

где первая перенаправляет как stdout, так и stderr в файл, последний перенаправляет stderr туда, где stdout идет до перенаправления на файл (в данном случае, вероятно, на терминал). Это полезно, если вы хотите что-то сделать как:

команда 2 > & 1 > файл | меньше

Если вы хотите использовать меньше на странице через вывод stderr и сохранить вывод stdout в файл.

Ответ 7

2>&1 может быть полезна для случаев, когда вы не перенаправляете stdout в другое место, а скорее хотите, чтобы stderr был отправлен на одно и то же место (например, консоль) в качестве stdout (возможно, если команда запуск уже отправляет stderr в другое место, кроме консоли).

Ответ 8

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

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

где as:

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