Немедленно скажите, какой вывод был отправлен на stderr

2997
Clinton Blackmore

При автоматизации задачи целесообразно сначала проверить ее вручную. Было бы полезно, однако, если бы любые данные, поступающие в stderr, были сразу же распознаваемы как таковые и отличались от данных, поступающих в stdout, и иметь все выходные данные вместе, чтобы было очевидно, какова последовательность событий.

Последнее, что было бы неплохо, - при выходе из программы печатать код возврата.

Все эти вещи помогут в автоматизации. Да, я могу повторить код возврата после завершения программы, и да, я могу перенаправить stdout и stderr; что бы мне действительно понравилось, это какая-то оболочка, скрипт или простой в использовании редиректор, который показывает stdout черным цветом, показывает stderr, чередующийся с ним красным, и печатает код выхода в конце.

Есть ли такой зверь? [Если это имеет значение, я использую Bash 3.2 в Mac OS X].


Обновление : Извините, прошли месяцы с тех пор, как я смотрел на это. Я придумал простой тестовый скрипт:

#!/usr/bin/env python import sys  print "this is stdout" print >> sys.stderr, "this is stderr" print "this is stdout again" 

В моем тестировании (и, вероятно, из-за того, как все буферизовано), rse и hilite отображают все из stdout, а затем все из stderr. Метод fifo правильно определяет порядок, но, кажется, окрашивает все, что следует за строкой stderr. ind пожаловался на мои строки stdin и stderr, а затем поместил вывод stderr последним.

Большинство из этих решений работоспособны, так как нет ничего необычного в том, что только последний вывод идет в stderr, но все же было бы неплохо иметь что-то, что работало бы немного лучше.

8
Если вы ленивый (или у вас болят пальцы), как я, вы можете взять подоболочку с помощью приведенных ниже решений (например, rse zsh), и теперь все команды раскрашивают stderr. bias 13 лет назад 0

6 ответов на вопрос

9
jtbandes

Я только что разработал сумасшедший метод с участием FIFO.

$ mkfifo foo $ grep --color . foo & $ your_command 2>foo 

Если вы хотите, чтобы вывод stderr был отдельным, вы можете открыть две отдельные оболочки и запустить " grep --color . foo" в одной без &, затем запустить команду в другой (все еще с 2>foo). Вы получите stderr в grepодном и стандартный вывод в главном.

Это работает, потому что вывод stderr направляется через FIFO в grep --color, чей цвет по умолчанию красный (по крайней мере, для меня). Когда вы закончите, просто rmFIFO ( rm foo).

Предостережение : я действительно не уверен, как это будет обрабатывать порядок вывода, вам придется проверить его.

Это довольно гладко. Clinton Blackmore 14 лет назад 0
7
nagul

Да, это возможно. Посмотрите раздел «Сделайте STDERR красным» на этом сайте для рабочего примера.

Основной код это

# Red STDERR # rse <command string> function rse() { # We need to wrap each phrase of the command in quotes to preserve arguments that contain whitespace # Execute the command, swap STDOUT and STDERR, colour STDOUT, swap back ((eval $(for phrase in "$@"; do echo -n "'$phrase' "; done)) 3>&1 1>&2 2>&3 | sed -e "s/^\(.*\)$/$(echo -en \\033)[31;1m\1$(echo -en \\033)[0m/") 3>&1 1>&2 2>&3 } 

Краткое объяснение дается в самой функции. Что делает, так это перемещает STDOUT и STDERR, поэтому sed получает STDERR в 1, окрашивает его и затем меняет его обратно. Думайте о файловом потоке 3 как о временной переменной здесь.

Звонок довольно прост

rse commands 

Однако некоторые вызовы не будут работать так, как ожидалось; предостережения все представлены на связанной странице.

Кстати, я думаю, что также возможно прийти с решением в виде

commands | rse 

где rse раскрасит вывод.

Я также нашел этот HILITE проект, который, кажется, чтобы сделать это. Я не пробовал это, но это может быть то, что вы ищете.

hilite - это крошечная утилита, которая выполняет указанную вами команду, выделяя все, что было напечатано в stderr. Он предназначен в основном для использования со сборками, чтобы предупреждения и ошибки торчали как больное клише.

Другие связанные проекты:

rse и hilite довольно близки к тому, что я хочу. Clinton Blackmore 14 лет назад 0
3
sickill

Вы также можете проверить stderred: https://github.com/sickill/stderred

К сожалению, stderred разрывает слова «open» и «mvim» для пользователей Mac, таких как OP. AlcubierreDrive 12 лет назад 0
Это работает очень хорошо, и получает порядок вывода в соответствии с тем, как он работает. Настройте его один раз и включите в своем профиле, и вы получите красные сообщения всякий раз, когда в stderr записывается. Clinton Blackmore 12 лет назад 0
@JonRodriguez, мне кажется, что [проблема с командой "open" была исправлена] (https://github.com/sickill/stderred/issues/11). Clinton Blackmore 12 лет назад 1
1
Thomas

Еще одна программа ind:

http: // www.habets.pp.se/synscan/programs.php?prog=ind (вам нужно собрать гиперссылку самостоятельно, у меня не хватает точек для более чем одного ответа). Там есть скриншот и даже скринкаст.

Он запускает подпроцесс в pty, что другие, вероятно, не делают. Это может иметь значение, когда порядок имеет значение (это часто имеет значение), так как stderr немедленно сбрасывается в терминалах, а stdout полностью буферизуется, когда он не tty.

Для более подробного объяснения, смотрите это: http://blog.habets.pp.se/2008/06/Buffering-in-pipes

Также ind работает с интерактивными программами и управляющими персонажами. Bash работает как обычно, когда начинается с "ind bash -i".

Это может работать, чтобы дать вам цвета при сохранении Ctrl-P et.al.

ind -P $(echo -ne '\033[31;1m') -p $(echo -ne '\033[0m') bash -i 
1
srnka

Здесь много ответов для выделения вывода stderr. Я могу добавить только один довольно простой - в один ряд, который вы присоединяете к команде:

command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m"; done) 

Но вы должны добавлять это после команды каждый раз.

Лично мне нравится возможность, упомянутая @nagul, функция rse, добавленная в bashrc.

Но я хочу добавить решение для печати кода выхода. Вы можете добавить это значение в начало строки приглашения bash:

hostname$ command Some error occurred. Returned exit code. EC hostname$ 

Где EC - код выхода команды.

Я установил его так, что когда код выхода равен 0, он не будет напечатан, но любое другое значение будет напечатано перед следующей подсказкой красным цветом.

Весь трюк сделан в ~ / .bashrc:

my_prompt() { EXITSTATUS="$?" RED="\[\033[1;31m\]" OFF="\[\033[m\]"  PROMPT="$\h \$ "  if [ "$" -eq 0 ]; then PS1="$" else PS1="$$EXITSTATUS$ $" fi }  PROMPT_COMMAND=my_prompt 

Строка подсказки по умолчанию определяется переменной PS1. Скопируйте все, что у вас есть, в переменную PROMPT, а затем создайте переменную PS1 с кодом выхода или без него.

Bash покажет информацию в переменной PS1 в командной строке.

Это именно то, что я искал, спасибо! Dylon 7 лет назад 0
1
mykhal

есть annotate-outputутилита ( devscriptsпакет Debian), если вы хотите сделать это без цветов

$ annotate-output /tmp/test.py  14:24:57 I: Started /tmp/test.py 14:24:57 E: this is stderr 14:24:57 O: this is stdout 14:24:57 O: this is stdout again 14:24:57 I: Finished with exitcode 0