Подтвердить что ты не робот

Команда sh: exec 2> & 1

Что будет делать эта команда?

exec 2>&1 
4b9b3361

Ответ 1

С технической точки зрения он дублирует или копирует stderr на stdout.

Обычно вам не нужен exec для выполнения этого. Более типичное использование exec с файловыми дескрипторами - указать, что вы хотите назначить файл неиспользуемому файловому дескриптору, например

exec 35< my_input

BTW Не забывайте, что последовательность объявлений, когда сообщение в файл важно, поэтому

ls > mydirlist 2>&1

будет работать, потому что он направляет как stdout, так и stderr в файл mydirlist, тогда как команда

ls 2>&1 > mydirlist

направляет только stdout, а не stderr, на файл mydirlist, потому что stderr был сделан копией stdout, прежде чем stdout был перенаправлен на mydirlist.

Изменить: Это способ сканирования оболочки слева направо. Поэтому прочитайте второй вариант, говоря "copy stderr на stdout", прежде чем он скажет: "Отправить stdout для mydirlist". Затем прочитайте первый, указав "отправьте stdout в файл mydirlist", прежде чем он произнесет "duplicate stderr на этот stdout, который я настроил". Я знаю. Это совершенно не интуитивно!

Ответ 2

Одна из лучших статей, которые я видел по поводу того, что "2 > & 1" делает, Bash Объяснение одним слоем, часть III: все о перенаправлениях.

Но то, что текущие ответы на этот вопрос не дают, - это то, почему вы захотите сделать это после простого "exec". Поскольку справочная страница bash для команды exec объясняет: "Если команда не указана, любые перенаправления вступают в силу в текущей оболочке".

Я написал простой script вызываемый out-and-err.py, который записывает строку вывода в stdout, а другую строку - stderr:

#!/usr/bin/python
import sys
sys.stdout.write('this is stdout.\n')
sys.stderr.write('this is stderr.\n')

И затем я завернул, что в оболочке script вызывается out-and-err.sh с помощью "exec 2 > & 1":

#!/bin/bash
exec 2>&1
./out-and-err

Если я запускаю только python script, stdout и stderr являются отдельными:

$ ./out-and-err.pl 1> out 2> err
$ cat out
this is stdout.
$ cat err
the is stderr.

Но если я запустил оболочку script, вы увидите, что exec заботится о stderr для всего:

$ ./out-and-err.sh 1> out 2> err
$ cat out
this is stdout.
this is stderr.
$ cat err
$

Если ваша оболочечная оболочка script делает намного больше, чем только одна команда python, и вам нужен весь вывод, объединенный в stdout, выполнение "exec 2 > & 1" сделает это легко для вас.

Ответ 3

Он связывает стандартную ошибку со стандартным

2 - stderr, а 1 - stdout. Когда вы запускаете программу, вы получите нормальный вывод в stdout, но любые ошибки или предупреждения обычно идут в stderr. Если вы хотите связать весь вывод с файлом, например, сначала скомпоновать stderr с stdout с помощью 2>&1.

Ответ 4

Как и @cma, он ставит stderr на stdout. Причина, по которой вам может понадобиться такое поведение, - использовать grep или любую другую утилиту для захвата вывода, который появляется только на stderr. Или вы можете просто сохранить весь вывод, включая stderr, в файл для последующей обработки.

Ответ 5

Одним из весьма полезных приложений exec 2>&1, с которыми я столкнулся, является то, что вы хотите объединить stderr и stdout для нескольких команд, разделенных точками с запятой. Мой конкретный пример произошел, когда я отправлял более чем одну команду в popen в PHP, и мне хотелось, чтобы ошибки чередовали, как вы увидите, набрали ли вы команды в командной строке:

$ echo hi ; yikes ; echo there
hi
-bash: yikes: command not found
there
$ 

Следующее не объединяет stderr и stdout за исключением последнего echo (что бессмысленно, потому что ошибка yikes вызывает ошибку):

echo hi ; yikes ; echo there 2>&1

Я могу получить объединенный вывод "трудный путь" следующим образом:

echo hi 2>&1; yikes 2>&1; echo there 2>&1

Он выглядит намного чище и менее подвержен ошибкам, если вы используете exec:

exec 2>&1 ; echo hi; echo yikes; echo there

Вы получаете выходные данные stdout и stderr, как показано на терминале, если вы выполнили три команды, разделенные точкой с запятой.