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

Shell: перенаправление stdout на /dev/null и stderr на stdout

Я увидел этот интересный вопрос в комментарии cyberciti.biz.

Что я нашел, я даже не могу найти гибкий способ сделать это в однострочной команде с sh.

Насколько я понял, решение:

tmp_file=`mktemp`
(./script 2>$tmp_file >/dev/null; cat $tmp_file) | ./other-script
rm tmp_file

Но вы видите, это не синхронно, а смертельно, это так уродливо.

Добро пожаловать, чтобы поделиться своим мнением об этом.:)

4b9b3361

Ответ 1

Ты хочешь

./script 2>&1 1>/dev/null | ./other-script

Порядок здесь важен. Предположим, что stdin (fd 0), stdout (fd 1) и stderr (fd 2) изначально подключены к tty, поэтому

0: /dev/tty, 1: /dev/tty, 2: /dev/tty

Первое, что настраивается - это труба. other-script stdin подключается к каналу, а сценарий stdout подключается к каналу, поэтому дескрипторы файлов сценария до сих пор выглядят так:

0: /dev/tty, 1: pipe, 2: /dev/tty

Далее происходит перенаправление слева направо. 2>&1 заставляет fd 2 идти туда, куда в настоящее время идет fd 1, то есть канал.

0: /dev/tty, 1: pipe, 2: pipe

Наконец, 1>/dev/null перенаправляет fd1 в /dev/null

0: /dev/tty, 1: /dev/null, 2: pipe

Конечный результат, сценарий stdout отключается, и его stderr отправляется через канал, который заканчивается в stdin other-script.

Также см. Http://bash-hackers.org/wiki/doku.php/howto/redirection_tutorial

Также обратите внимание, что 1>/dev/null является синонимом, но более явным, чем >/dev/null

Ответ 2

Как насчет этого:

./script 3>&1 1>/dev/null 2>&3 | ./other-script

Идея заключается в "резервном" дескрипторе stdout, закрытии исходного stdout и последующем перенаправлении strerr на сохраненный stdout.

Его очень похоже на решение, предоставленное geirha, но его более явное (bash кодирование может легко стать очень затененным).

Ответ 3

Хорошо, это потому, что вы не можете. STDOUT и STDERR - это всего лишь два файла, представленные файловыми дескрипторами, которые являются целыми числами, в частности 1 и 2.

То, что вы просите, - установить дескриптор 2 на /dev/null, затем установить дескриптор 3 в тот же дескриптор файла 2 и получить этот вывод в другом месте.