Natychmiast powiedz, które wyjście zostało wysłane do stderr

8

Podczas automatyzacji zadania warto najpierw przetestować je ręcznie. Byłoby jednak pomocne, gdyby jakiekolwiek dane idące do stderr były natychmiast rozpoznawalne jako takie i odróżnialne od danych idących na standardowe wyjście, i aby wszystkie dane wyjściowe były zebrane razem, więc jest oczywiste, jaka jest sekwencja zdarzeń.

Ostatni dotyk, który byłby miły, to to, że przy wyjściu programu wypisuje swój kod powrotu.

Wszystkie te rzeczy pomogłyby w automatyzacji. Tak, mogę powtórzyć kod powrotu po zakończeniu programu i tak, mogę przekierować stdout i stderr; to, co naprawdę chciałbym, to jakaś powłoka, skrypt lub łatwy w użyciu readresator, który pokazuje stdout na czarno, pokazuje stderr przeplatany z nim na czerwono i drukuje kod wyjścia na końcu.

Czy jest taka bestia? [Jeśli to ważne, używam Bash 3.2 na Mac OS X].


Aktualizacja : Przepraszam, że minęły miesiące, odkąd na to spojrzałem. Wymyśliłem prosty skrypt testowy:

#!/usr/bin/env python
import sys

print "this is stdout"
print >> sys.stderr, "this is stderr"
print "this is stdout again"

W moich testach (i prawdopodobnie ze względu na sposób buforowania), rse i hilite wyświetlają wszystko od standardowego, a potem od standardowego. Metoda FIFO porządkuje porządek, ale wydaje się, że wszystko koloryzuje zgodnie z linią stderr. ind narzekał na moje linie stdr i stderr, a następnie odłożył wyjście z stderr na końcu.

Większość z tych rozwiązań jest wykonalna, ponieważ nie jest nietypowe, że tylko ostatni wynik przechodzi do stderr, ale nadal byłoby miło mieć coś, co działałoby nieco lepiej.

Clinton Blackmore
źródło
Jeśli jesteś leniwy (lub masz obolałe palce) jak ja, możesz złapać podpowłokę z poniższymi rozwiązaniami (np. Rse zsh), a teraz wszystkie polecenia kolorują stderr.
stronniczość

Odpowiedzi:

3

Możesz także sprawdzić stderred: https://github.com/sickill/stderred

chory
źródło
Niestety, szeregowanie przerywa „otwarte” i „mvim” dla użytkowników komputerów Mac, takich jak OP.
AlcubierreDrive,
Działa to bardzo ładnie i odpowiednio porządkuje dane wyjściowe ze względu na sposób działania. Skonfiguruj go raz i włącz go w swoim profilu, a będziesz otrzymywać czerwone wiadomości za każdym razem, gdy zapisany jest stderr.
Clinton Blackmore,
1
@JonRodriguez, wydaje mi się, że problem z poleceniem „otwórz” został naprawiony .
Clinton Blackmore,
9

Właśnie opracowałem szaloną metodę z udziałem FIFO.

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

Jeśli chcesz, aby wyjście stderr było oddzielne, możesz otworzyć dwie osobne powłoki i uruchomić „ grep --color . foo” w jednym bez &, a następnie uruchomić polecenie w drugim (nadal z 2>foo). Dostaniesz stderr w grepjednym, a stdout w głównym.

Działa to, ponieważ wyjście stderr jest kierowane przez FIFO do grep --color, którego domyślnym kolorem jest czerwony (przynajmniej dla mnie). Kiedy skończysz, wystarczy rmFIFO ( rm foo).

Zastrzeżenie : Naprawdę nie jestem pewien, jak to będzie obsługiwać kolejność wyjściową, będziesz musiał to przetestować.

jtbandes
źródło
To całkiem sprytne.
Clinton Blackmore,
7

Tak, jest to możliwe. Zobacz dział „Zmień STDERR na czerwony” na tej stronie, aby znaleźć działający przykład.

Podstawowy kod jest taki

# 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
}

Krótkie wyjaśnienie znajduje się w samej funkcji. Przesuwa STDOUT i STDERR, więc sed pobiera STDERR w 1, koloruje go, a następnie zamienia z powrotem. Potraktuj strumień pliku 3 jako zmienną temp tutaj.

Połączenie jest dość proste

rse commands

Jednak niektóre wywołania nie będą działać zgodnie z oczekiwaniami; wszystkie zastrzeżenia znajdują się na połączonej stronie.

Przy okazji, myślę, że możliwe jest również rozwiązanie tego formularza

commands | rse 

gdzie rse pokoloruje wydruk.

Znalazłem też ten hilite projekt, który wydaje się to robić. Nie wypróbowałem tego, ale to może być to, czego szukasz.

hilite to małe narzędzie, które wykonuje określone polecenie, podświetlając wszystko wydrukowane na stderr. Jest przeznaczony głównie do użytku z kompilacjami, aby ostrzeżenia i błędy wystrzeliły jak obolały frazes.

Inne powiązane projekty:


źródło
rse i hilite są bardzo blisko tego, czego chcę.
Clinton Blackmore,
1

Innym programem jest ind:

http: // www.habets.pp.se/synscan/programs.php?prog=ind (sam musisz skompletować hiperłącze, nie mam wystarczającej liczby punktów dla więcej niż jednego na odpowiedź). Jest tam zrzut ekranu, a nawet zrzut ekranu.

Prowadzi podproces w pty, czego inni prawdopodobnie nie robią. Może to mieć znaczenie tam, gdzie liczy się kolejność (często tak jest), ponieważ stderr jest natychmiast opróżniany w terminalach, a stdout jest w pełni buforowany, gdy nie jest tty.

Aby uzyskać pełne wyjaśnienie, zobacz: http://blog.habets.pp.se/2008/06/Buffering-in-pipes

Ind działa również z interaktywnymi programami i znakami kontrolnymi. Bash działa tak jak normalnie, gdy zaczyna się od „ind bash -i”.

Może to działać w celu uzyskania kolorów przy jednoczesnym zachowaniu Ctrl-P i in.

ind -P $(echo -ne '\033[31;1m') -p $(echo -ne '\033[0m') bash -i
Tomasz
źródło
1

Oto wiele odpowiedzi na temat podświetlania wyników stderr. Mogę dodać tylko jeden dość łatwy - w jednym rzędzie, który dołączasz do polecenia:

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

Ale za każdym razem musisz to dodać po poleceniu.

Ja osobiście podoba mi się możliwość wspomniana przez @nagul, funkcja rse dodana do bashrc.

Ale chcę dodać rozwiązanie do drukowania kodu wyjścia. Możesz dodać tę wartość na początku wiersza polecenia bash:

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

Gdzie EC jest kodem wyjścia polecenia.

Mam to ustawione w taki sposób, że gdy kod wyjścia ma wartość 0, nie zostanie wydrukowany, ale każda inna wartość zostanie wydrukowana przed następnym monitem w kolorze czerwonym.

Cała sztuczka odbywa się w ~ / .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

Wiersz zachęty jest domyślnie zdefiniowany przez zmienną PS1. Skopiuj cokolwiek masz tutaj do zmiennej PROMPT, a następnie utwórz zmienną PS1 z kodem wyjścia lub bez.

Bash wyświetli informację w zmiennej PS1 w pytaniu.

srnka
źródło
Właśnie tego szukałem, dzięki!
Dylon,
1

jest annotate-outputnarzędzie ( devscriptspakiet Debian), jeśli chcesz to zrobić bez kolorów

$ 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
źródło