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

8

При автоматизации задачи целесообразно сначала проверить ее вручную. Было бы полезно, однако, если бы любые данные, поступающие в 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, но все же было бы неплохо иметь что-то, что работало бы немного лучше.

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

Ответы:

3

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

sickill
источник
К сожалению, stderred разрывает слова «open» и «mvim» для пользователей Mac, таких как OP.
AlcubierreDrive
Это работает очень хорошо, и получает порядок вывода в соответствии с тем, как он работает. Установите его один раз и включите в своем профиле, и вы получите красные сообщения всякий раз, когда в stderr записывается.
Клинтон Блэкмор
1
@JonRodriguez, мне кажется, что проблема с командой "open" была исправлена .
Клинтон Блэкмор
9

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

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

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

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

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

jtbandes
источник
Это довольно гладко.
Клинтон Блэкмор
7

Да, это возможно Посмотрите на раздел «Сделайте 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 довольно близки к тому, что я хочу.
Клинтон Блэкмор
1

Еще одна программа 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

Здесь много ответов для выделения вывода 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="${debian_chroot:+($debian_chroot)}\h \$ "

if [ "${EXITSTATUS}" -eq 0 ]; then
   PS1="${PROMPT}"
else
   PS1="${RED}$EXITSTATUS${OFF} ${PROMPT}"
fi
}

PROMPT_COMMAND=my_prompt

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

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

Srnka
источник
Это именно то, что я искал, спасибо!
Dylon
1

есть 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
mykhal
источник