Какая разница между "&> 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" ) # отлично работает!