Как перейти на stderr?

Я хочу разделить stdout, чтобы он печатался как в stdout, так и в stderr. Звучит как работа для tee, но синтаксис ускользает от меня -

./script.sh | tee stderr

Конечно, как на самом деле здесь следует ссылаться на stderr?


person djechlin    schedule 10.12.2012    source источник
comment
@JonathanLeffler Существуют системы с / dev / fd, но без символических ссылок stderr, stdout. Думаю, сюда входит Солярис? У некоторых из них, таких как HP-UX, AIX, Irix, конечно, нет / dev / fd, но есть все нормальные системы.   -  person Nicholas Wilson    schedule 10.12.2012
comment
Мое плохое, в Solaris 8 и 9 действительно есть / dev / stderr ...   -  person Nicholas Wilson    schedule 10.12.2012
comment
Действительно? В Solaris 10 есть /dev/stderr. Я не встречал системы с /dev/fd, в которой также не было бы /dev/std{in,out,err}, но это не значит, что их не существует. В Mac OS X 10.7.5 есть и то, и другое; В Solaris есть и то, и другое; В Linux есть и то, и другое. В AIX 6 нет ни того, ни другого; HP-UX 11.00 не имеет ни того, ни другого.   -  person Jonathan Leffler    schedule 10.12.2012
comment
Возможный обман с множеством потенциальных ответов: stackoverflow.com/questions/692000/   -  person Eric Leschinski    schedule 10.12.2012
comment
bash принимает /dev/stderr как синоним стандартной ошибки независимо от того, существует ли файл в файловой системе; это особый случай.   -  person chepner    schedule 10.12.2012
comment
Что касается /dev/fd/2 и /dev/stderr; Руководство bash по перенаправлениям: Bash обрабатывает несколько имен файлов специально, когда они используются в перенаправлениях , ...   -  person Joel Purra    schedule 28.11.2013


Ответы (3)


./script.sh | tee /dev/fd/2

Обратите внимание, что это зависит от поддержки ОС, а не от встроенного питания в тройнике, поэтому не универсален (но будет работать на MacOS, Linux, Solaris, FreeBSD и, возможно, на других).

person Nicholas Wilson    schedule 10.12.2012
comment
Чтобы лучше понять, что происходит за кулисами в приведенной выше команде, прочтите сайт хакеров bash о перенаправлении: wiki.bash-hackers.org/syntax/redirection - person Eric Leschinski; 10.12.2012
comment
Это не совсем перенаправление, не так ли? Это просто синтаксис канала. Аргумент / dev / fd / 2 непрозрачен для оболочки; он только устанавливает stdin fd для дочернего элемента tee, который является процессом, который интерпретирует аргумент (как имя файла, чтобы получить выходной fd с open()). - person Nicholas Wilson; 10.12.2012
comment
Страница руководства для bash подразумевает, что она принимает /dev/fd/2 в качестве имени файла для файлового дескриптора 2, даже если файловая система не имеет такого файла. - person chepner; 10.12.2012
comment
@chepner Это интересно. Но в этом примере имя файла никогда не интерпретируется bash, так что здесь это не играет роли. - person Nicholas Wilson; 10.12.2012
comment
О верно. Это будет работать с перенаправлением, но не в качестве аргумента для tee. - person chepner; 11.12.2012
comment
Обратите внимание, что он может не работать в зависимости от того, что именно /dev/fd/2. Например, если вы войдете в систему как root, ваш терминал будет принадлежать root. Затем, если вы смените пользователя, у вас не будет доступа к /dev/fd/2. - person Michał Górny; 06.09.2013
comment
Кроме того, /proc/self/fd/2 может быть что-то доступно. фактически, в моей системе [CentOS6] /dev/fd является символической ссылкой на /proc/self/fd. - person Sammitch; 04.05.2016

Единственный найденный мной кроссплатформенный метод, который работает как в интерактивных, так и в неинтерактивных оболочках:

command | tee >(cat 1>&2)

Аргумент tee - это файл или дескриптор файла. Используя подстановку процесса, мы отправляем результат процессу. В process = cat = мы перенаправляем stdout на stderr. Оболочка (bash / ksh) отвечает за настройку файловых дескрипторов 1 и 2.

person brianegge    schedule 12.12.2013
comment
Не забудьте добавить #!/bin/bash, если он запускается в сценарии. Поскольку sh не поддерживает >( xxxx ) - person Sungam; 01.01.2021

./script.sh 2>&1 >/dev/null | tee stderr.out

Это открывает STDERR для STDOUT, а затем удаляет STDOUT.

person David W.    schedule 10.12.2012
comment
Это направляет весь вывод в /dev/null. - person Lex R; 28.07.2016
comment
Он не передает все в / dev / null, только stdout script.sh. Stderr script.sh переходит к stdin tee, а tee пишет, что все для stdout tee и файла stderr.out ... Это не то, о чем просили в вопросе, но это именно то, что я ищу, поэтому +1 от меня :-) - person David L.; 27.02.2017