Как понять порядок перенаправления вывода? [дубликат]

Итак, я пытаюсь научиться передавать стандартные ошибки и стандартные ошибки в различные области.

Допустим, у меня есть папка только с 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? Почему?

10
задан 24 September 2017 в 12:53

3 ответа

Порядок перенаправлений является значительным. Например, команда

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:~$ 
5
ответ дан 23 November 2019 в 04:33
  • 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 здесь не использован программами).

3
ответ дан 23 November 2019 в 04:33

Обнаружение оболочки и наборы в порядке это видит вещь. В первом случае:

ls here.txt not-here.txt  1>out  2>&1

вывод перенаправляется, затем стандартная погрешность отправляется в то же место.

Во втором случае,

ls here.txt not-here.txt 2>&1 1>out

Standardout все еще установлен на терминал, таким образом, стандартная погрешность отправляется на терминал ЗАТЕМ, стандарт изменяется. Оболочка уже установила стандартную погрешность.

2
ответ дан 23 November 2019 в 04:33

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

Похожие вопросы: