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, но все же было бы неплохо иметь что-то, что работало бы немного лучше.

6 ответов6

9

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

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

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

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

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

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. Он предназначен в основном для использования со сборками, чтобы предупреждения и ошибки торчали как больное клише.

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

3

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

1

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

$ 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
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 в командной строке.

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