На этот вопрос уже есть ответ здесь:
Итак, я пытаюсь научиться передавать стандартные ошибки и стандартные ошибки в различные области.
Допустим, у меня есть папка только с here.txt
.
Итак, если я сделаю
ls here.txt not-here.txt 1>out 2>&1
Поскольку присутствует here.txt
, у меня будет какой-то вывод для направления в файл out
, но поскольку not-here.txt
отсутствует, сообщение об ошибке будет отправлено через стандартную ошибку, которую я перенаправляю на стандартный вывод с помощью 2> & 1
.
Однако почему это не работает:
ls here.txt not-here.txt 2>&1 1>out
Кажется, это работает, только если я выполняю перенаправление после стандартной инструкции out? Почему?
Порядок перенаправлений является значительным. Например, команда
ls > dirlist 2>&1
направляет и стандартный вывод и стандартную погрешность в файл dirlist, в то время как команда
ls 2>&1 > dirlist
направляет только стандартный вывод к файлу dirlist, потому что стандартная погрешность была дублирована от стандартного вывода (обычно все еще указывающий на окно терминала), прежде чем стандартный вывод был перенаправлен к dirlist.
Сначала это может чувствовать себя парадоксальным, но после размышления об этом, мы можем понять это.
Вы находите это объяснение в man bash
, в главе о перенаправлении,
ПЕРЕНАПРАВЛЕНИЕ
Прежде чем команда выполняется, ее ввод и вывод может быть перенаправлен с помощью специальной нотации, интерпретируемой оболочкой. Перенаправление позволяет дескрипторам файлов команд быть дублированными, открытыми, закрытыми, сделанными относиться к различным файлам, и может изменить файлы чтения команды от и пишет в. Перенаправление может также использоваться для изменения дескрипторов файлов в текущей среде выполнения оболочки. Следующие операторы перенаправления могут предшествовать или появиться где угодно в рамках простой команды или могут следовать за командой. Перенаправления обрабатываются в порядке, они появляются, слева направо.
Каждому перенаправлению, которому может предшествовать число дескриптора файла, может вместо этого предшествовать слово формы
{varname}
. В этом случае, для каждого оператора перенаправления кроме>&-
и<&-
, оболочка будет выделять дескриптор файла, больше, чем, или равняться 10 и присваивать егоvarname
. Если>&-
или<&-
предшествуют{varname}
, значениеvarname
определяет дескриптор файла для закрытия.В следующих описаниях, если число дескриптора файла опущено, и первый символ оператора перенаправления
<
, перенаправление относится к стандартному входу (дескриптор файла 0). Если первый символ оператора перенаправления>
, перенаправление относится к стандартному выводу (дескриптор файла 1).Слово после оператора перенаправления в следующих описаниях, если не указано иное, подвергается для заключения в фигурные скобки расширения, расширения тильды, параметра и переменного расширения, замены команды, арифметического расширения, удаления кавычки, расширения пути и разделения слова. Если это расширяется больше чем до одного слова, удар сообщает об ошибке.
Обратите внимание, что порядок перенаправлений является значительным. Например, команда
ls > dirlist 2>&1
направляет и стандартный вывод и стандартную погрешность в файл
dirlist
, в то время как командаls 2>&1 > dirlist
направляет только стандартный вывод к файлу
dirlist
, потому что стандартная погрешность была дублирована от стандартного вывода, прежде чем стандартный вывод был перенаправлен кdirlist
.
Править: Следующие командные строки могли бы объяснить, что происходит
Подготовиться
sudodus@xenial32:~$ touch qwerty;rm asdf
rm: cannot remove 'asdf': No such file or directory
Выполните команду списка для одного существующего файла и одного несуществующего файла
sudodus@xenial32:~$ ls qwerty asdf
ls: cannot access 'asdf': No such file or directory
qwerty
Перенаправьте вывод ошибок прежде, чем перенаправить стандартный вывод. Только стандартный вывод перенаправляется к выходному файлу.
sudodus@xenial32:~$ ls qwerty asdf 2>&1 > output-file ;echo '---';cat output-file
ls: cannot access 'asdf': No such file or directory
---
qwerty
Перенаправьте вывод ошибок после перенаправления стандартного вывода. И вывод ошибок и стандартный вывод перенаправляются к выходному файлу.
sudodus@xenial32:~$ ls qwerty asdf > output-file 2>&1 ;echo '---';cat output-file
---
ls: cannot access 'asdf': No such file or directory
qwerty
Маркер &>
может использоваться для перенаправления и стандартной погрешности и стандартного вывода. Это может использоваться в bash
, но может не быть доступным в других оболочках.
sudodus@xenial32:~$ ls qwerty asdf &> output-file ;echo '---';cat output-file
---
ls: cannot access 'asdf': No such file or directory
qwerty
sudodus@xenial32:~$
2>x
средства, что имя файла x
получит данные, записанные в дескриптор 2
(также известный как stderr, стандартная погрешность) x
будет указан как &1
, это не означает, "всегда следуют 1
"; это означает , "копируют текущие свойства 1
(и затем оставляют его в покое)", . Это то, почему 2>&1 1>whatever
выводы stderr к терминалу.
Поэтому find / -name mylostfile.txt 3>&1 1>&2 2>&3 | grep -v 'Permission denied'
обмены stderr и stderr, так, чтобы можно было фильтровать некоторые общие stderr строки, но все еще видеть весь stdout. (Дескриптор 3 здесь не использован программами).
Обнаружение оболочки и наборы в порядке это видит вещь. В первом случае:
ls here.txt not-here.txt 1>out 2>&1
вывод перенаправляется, затем стандартная погрешность отправляется в то же место.
Во втором случае,
ls here.txt not-here.txt 2>&1 1>out
Standardout все еще установлен на терминал, таким образом, стандартная погрешность отправляется на терминал ЗАТЕМ, стандарт изменяется. Оболочка уже установила стандартную погрешность.