3

Может кто-нибудь, пожалуйста, уточнить различия? Некоторые из них считаются лучшей практикой? Если я правильно помню, я как-то на SO читал, что это 1>/dev/null должно предшествовать этому: 2>&1

ls -al /doesNotExists 2>&1 1>/dev/null
ls -al /doesNotExists 1>/dev/null 2>&1

ls -al /doesNotExists 1>&2 2>/dev/null
ls -al /doesNotExists 2>/dev/null 1>&2

ls -la /doesNotExists 2<&1 1>/dev/null
ls -la /doesNotExists 2<&1 2>/dev/null

ls -la /doesNotExists 1<&2 1>/dev/null
ls -la /doesNotExists 1<&2 2>/dev/null

ls -la /doesNotExists 1>/dev/null 2<&1
ls -la /doesNotExists 2>/dev/null 2<&1

ls -la /doesNotExists 1>/dev/null 1<&2
ls -la /doesNotExists 2>/dev/null 1<&2

1 ответ1

7

порядок перенаправления стандартных потоков оболочки

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

ls -al /doesNotExists 2>&1 1>/dev/null

Это направляет только стандартный вывод на nul, потому что стандартная ошибка была продублирована на стандартный вывод до того, как стандартный вывод был перенаправлен на dirlist.

ls -al /doesNotExists 1>/dev/null 2>&1

Это направляет как стандартный вывод, так и стандартную ошибку в nul.


Справочное руководство Bash: Перенаправления

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

ls > dirlist 2>&1

направляет как стандартный вывод (дескриптор файла 1), так и стандартную ошибку (дескриптор файла 2) в файл dirlist, а команда

ls 2>&1 > dirlist

направляет только стандартный вывод в файл dirlist, потому что при стандартной ошибке была сделана копия стандартного вывода до того, как стандартный вывод был перенаправлен в dirlist.

Source Bash Справочное руководство: Перенаправления


Руководство

В Illustrated Redirection Tutorial есть хороший иллюстрированный учебник, который облегчает понимание:

Порядок перенаправления, т. Е. "> Файл 2> & 1" против "2> & 1> файл"

Хотя не имеет значения, где перенаправления появляются в командной строке, их порядок имеет значение. Они настроены слева направо.

2>&1 >file

Распространенной ошибкой является выполнение команды 2> & 1> file для перенаправления как stderr, так и stdout в файл. Посмотрим, что происходит. Сначала мы набираем команду в нашем типичном терминале, дескрипторы выглядят так:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

Затем наша оболочка Bash видит 2> & 1, поэтому она дублирует 1, и дескриптор файла выглядит следующим образом:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

Правильно, ничего не изменилось, 2 уже указывал на то же место, что и 1. Теперь Bash видит> файл и таким образом меняет стандартный вывод:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| file                  |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

И это не то, что мы хотим.

>file 2>&1

Теперь давайте посмотрим на правильную команду> file 2> & 1. Мы начинаем как в предыдущем примере, и Bash видит> file:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| file                  |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

Затем он видит наше дублирование 2> & 1:

                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/5            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| file                  |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| file                  |
                  ---       +-----------------------+

И вуаля, и 1 и 2 перенаправлены в файл.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .