Wydaje mi się, że bash nigdy nie pokoloruje danych wyjściowych: jakiś program może chcieć coś przeanalizować, a kolorowanie zepsuje dane za pomocą sekwencji specjalnych. Chyba aplikacja GUI powinna obsługiwać kolory.
kolypto
Połączenie odpowiedzi Balázsa Pozsára i killdash9 daje ostry: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') } działa na bash i zsh. Nie można tego dodać jako reputacji b / c.
Heinrich Hartmann
1
Czekam na odpowiedź, która modyfikuje bash, aby to zrobić. Wszystkie poniższe rozwiązania faktycznie modyfikują stderr, a być może nawet zmieniają jego kolejność na standardowe, co psuje rzeczy, gdy zachowana musi być dokładna sekwencja bajtów stderr, np. Podczas instalacji.
Wspaniały! Ale zastanawiam się, czy jest jakiś sposób, aby to zrobić na stałe :)
kolypto
9
Świetna wskazówka! Sugestia: Dodając już >&2wcześniej ; done), wyjście przeznaczone dla stderr faktycznie jest zapisywane do stderr. Jest to pomocne, jeśli chcesz uchwycić normalne wyjście programu.
henko
8
Następujące zastosowania tput, i moim zdaniem, są nieco bardziej czytelne:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
Stefan Lasiewski
2
Myślę, że wykonanie 2 procesów tput dla każdej linii wyjściowej wcale nie jest eleganckie. Może gdybyś zapisał dane wyjściowe poleceń tput w zmiennej i używałby ich dla każdego echa. Ale z drugiej strony czytelność nie jest tak naprawdę lepsza.
Balázs Pozsár
1
To rozwiązanie nie zachowuje białych znaków, ale lubię je za zwięzłość. IFS= read -r linepowinien pomóc, ale nie pomaga. Nie pewny dlaczego.
Czytaj dalej, aby wyjaśnić, jak działa metoda 2. Polecenie to pokazuje kilka interesujących funkcji.
color()... - Tworzy funkcję bash o nazwie kolor.
set -o pipefail- To jest opcja powłoki, która zachowuje kod powrotu błędu polecenia, którego dane wyjściowe są przesyłane do innego polecenia. Odbywa się to w podpowłoce, która jest tworzona w nawiasach, aby nie zmieniać opcji pipefail w zewnętrznej powłoce.
"$@"- Wykonuje argumenty funkcji jako nowe polecenie. "$@"jest równa"$1" "$2" ...
2>&1- Przekierowuje stderrpolecenie, aby stdoutstało się sed's stdin.
>&3- Skrótowo oznacza 1>&3to przekierowanie stdoutdo nowego tymczasowego deskryptora pliku 3. 3wraca stdoutpóźniej.
sed ...- Z powodu powyższych przekierowań, sed„s stdinjest stderrod wykonywanego polecenia. Jego funkcją jest otaczanie każdej linii kodami kolorów.
$'...' Konstrukcja bash, która powoduje, że rozumie znaki ucieczki odwrotnego ukośnika
.* - Pasuje do całej linii.
\e[31m - Sekwencja zmiany znaczenia ANSI, która powoduje, że następujące znaki są czerwone
&- Znak sedzastępujący, który rozwija się do całego dopasowanego łańcucha (w tym przypadku cała linia).
\e[m - Sekwencja ucieczki ANSI, która resetuje kolor.
>&2- skrótem 1>&2, to przekierowuje sed„s stdoutdo stderr.
3>&1- Przekierowuje deskryptor pliku tymczasowego z 3powrotem do stdout.
Dlaczego musisz wykonać wszystkie dodatkowe przekierowania? wydaje się jak przesada
qodeninja
1
Czy istnieje sposób, aby to zadziałało zsh?
Eyal Levin,
1
ZSH nie rozpoznaje skrótowych form przekierowania. Potrzebuje tylko dwóch kolejnych 1, tj .:zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
Wow, to narzędzie jest świetne, jedyne, czego potrzebuje, to mieć apt repozytorium, które instaluje je dla wszystkich użytkowników, w jednym wierszu, bez konieczności wykonywania dodatkowej pracy, aby je włączyć.
sorin,
Wydawało się, że działa dobrze, gdy przetestowałem go za pomocą skryptu kompilacji w osobnym terminalu, ale waham się używać go globalnie (w .bashrc). W każdym razie dzięki!
Joel Purra
2
W OS X El Capitan sposób, w jaki to działa (DYLD_INSERT_LIBRARIES) jest „uszkodzony” w binariach systemowych, ponieważ są chronione przez SIP. Dlatego może być lepiej użyć opcji bash podanych w innych odpowiedziach.
hmijail 22.04.16
1
@hmijail dla MacOS postępuj zgodnie z github.com/sickill/stderred/issues/60 , abyśmy mogli znaleźć obejście, częściowe już istnieje, ale jest trochę wadliwe.
sorin
15
Podstawowym sposobem, aby stderr był trwale czerwony, jest użycie „exec” do przekierowania strumieni. Dodaj następujące elementy do swojego bashrc:
Jak dotąd najlepsza odpowiedź; łatwa do wdrożenia bez instalacji / wymagająca uprawnień sudo i może być uogólniona na wszystkie polecenia.
Luke Davis,
1
Niestety nie działa to dobrze z łańcuchem poleceń (Command && nextCommand || errorHandlerCommand). Wyjście błędu następuje po wyjściu errorHandlerCommand.
carlin.scott
1
Podobnie, jeśli zrobię to source ~/.bashrcdwa razy, mój terminal zasadniczo się zablokuje.
Dolph
@Dolf: W moim bashrc z łatwością chronię się przed tym za pomocą instrukcji otaczającej if, aby zapobiec przeładowaniu tego kodu. W przeciwnym razie problemem jest przekierowanie „exec 9> i 2” po tym, jak przekierowanie już miało miejsce. Być może zmień go na stałą, jeśli wiesz, gdzie> 2 wskazuje pierwotnie.
Zrobiłem skrypt otoki, który implementuje odpowiedź Balázsa Pozsár w czystym bashu. Zapisz go w komendach $ PATH i prefiksach, aby pokolorować ich dane wyjściowe.
#! / bin / bash
if [$ 1 == "--help"]; następnie
echo „Wykonuje polecenie i koloruje wszystkie napotkane błędy”
echo "Przykład:` basename $ {0} `wget ..."
echo "(c) o_O Tync, ICQ # 1227-700, Enjoy!"
wyjście 0
fi
# Plik tymczasowy, aby przechwycić wszystkie błędy
TMP_ERRS = $ (mktemp)
# Wykonaj polecenie
"$ @" 2>> (podczas odczytu linii; wykonaj echo -e "\ e [01; 31m $ line \ e [0m" | tee - dołącz $ TMP_ERRS; gotowe)
EXIT_CODE = $?
# Wyświetl ponownie wszystkie błędy
jeśli [-s „$ TMP_ERRS”]; następnie
echo -e "\ n \ n \ n \ e [01; 31m === BŁĘDY === \ e [0m”
kot $ TMP_ERRS
fi
rm -f $ TMP_ERRS
# Koniec
wyjdź z $ EXIT_CODE
Nie rozwiązuje problemu. Nie podałeś sposobu na oddzielenie stderr od stdout, czym interesuje się OP.
Jeremy Visser
1
Mam nieco zmodyfikowaną wersję skryptu O_o Tync. Musiałem zrobić te mody dla OS X Lion i nie jest to idealne, ponieważ skrypt czasami kończy się, zanim zrobi to zapakowane polecenie. Dodałem sen, ale jestem pewien, że jest lepszy sposób.
#!/bin/bashif[ $1 =="--help"];then
echo "Executes a command and colorizes all errors occured"
echo "Example: `basename ${0}` wget ..."
echo "(c) o_O Tync, ICQ# 1227-700, Enjoy!"
exit 0fi# Temp file to catch all errors
TMP_ERRS=`mktemp /tmp/temperr.XXXXXX`|| exit 1# Execute command"$@"2>>(while read line;do echo -e "$(tput setaf 1)$line\n"| tee -a $TMP_ERRS;done)
EXIT_CODE=$?
sleep 1# Display all errors againif[-s "$TMP_ERRS"];then
echo -e "\n\n\n$(tput setaf 1) === ERRORS === "
cat $TMP_ERRS
else
echo "No errors collected in $TMP_ERRS"fi
rm -f $TMP_ERRS
# Finish
exit $EXIT_CODE
# 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>&11>&22>&3| sed -e "s/^\(.*\)$/$(echo -en \\033)[31;1m\1$(echo -en \\033)[0m/")3>&11>&22>&3}
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
działa na bash i zsh. Nie można tego dodać jako reputacji b / c.Odpowiedzi:
źródło
>&2
wcześniej; done)
, wyjście przeznaczone dla stderr faktycznie jest zapisywane do stderr. Jest to pomocne, jeśli chcesz uchwycić normalne wyjście programu.tput
, i moim zdaniem, są nieco bardziej czytelne:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
IFS= read -r line
powinien pomóc, ale nie pomaga. Nie pewny dlaczego.Metoda 1: Użyj podstawienia procesu:
Metoda 2: Utwórz funkcję w skrypcie bash:
Użyj tego w ten sposób:
Obie metody pokażą komendę na
stderr
czerwono.Czytaj dalej, aby wyjaśnić, jak działa metoda 2. Polecenie to pokazuje kilka interesujących funkcji.
color()...
- Tworzy funkcję bash o nazwie kolor.set -o pipefail
- To jest opcja powłoki, która zachowuje kod powrotu błędu polecenia, którego dane wyjściowe są przesyłane do innego polecenia. Odbywa się to w podpowłoce, która jest tworzona w nawiasach, aby nie zmieniać opcji pipefail w zewnętrznej powłoce."$@"
- Wykonuje argumenty funkcji jako nowe polecenie."$@"
jest równa"$1" "$2" ...
2>&1
- Przekierowujestderr
polecenie, abystdout
stało sięsed
'sstdin
.>&3
- Skrótowo oznacza1>&3
to przekierowaniestdout
do nowego tymczasowego deskryptora pliku3
.3
wracastdout
później.sed ...
- Z powodu powyższych przekierowań,sed
„sstdin
jeststderr
od wykonywanego polecenia. Jego funkcją jest otaczanie każdej linii kodami kolorów.$'...'
Konstrukcja bash, która powoduje, że rozumie znaki ucieczki odwrotnego ukośnika.*
- Pasuje do całej linii.\e[31m
- Sekwencja zmiany znaczenia ANSI, która powoduje, że następujące znaki są czerwone&
- Znaksed
zastępujący, który rozwija się do całego dopasowanego łańcucha (w tym przypadku cała linia).\e[m
- Sekwencja ucieczki ANSI, która resetuje kolor.>&2
- skrótem1>&2
, to przekierowujesed
„sstdout
dostderr
.3>&1
- Przekierowuje deskryptor pliku tymczasowego z3
powrotem dostdout
.źródło
zsh
?zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
Możesz także sprawdzić stderred: https://github.com/sickill/stderred
źródło
.bashrc
). W każdym razie dzięki!Podstawowym sposobem, aby stderr był trwale czerwony, jest użycie „exec” do przekierowania strumieni. Dodaj następujące elementy do swojego bashrc:
Wcześniej napisałem na ten temat: Jak ustawić kolor czcionki dla STDOUT i STDERR
źródło
source ~/.bashrc
dwa razy, mój terminal zasadniczo się zablokuje.http://sourceforge.net/projects/hilite/
źródło
Zrobiłem skrypt otoki, który implementuje odpowiedź Balázsa Pozsár w czystym bashu. Zapisz go w komendach $ PATH i prefiksach, aby pokolorować ich dane wyjściowe.
źródło
Możesz użyć takiej funkcji
Dołączam> i 2, aby wydrukować na stderr
źródło
Mam nieco zmodyfikowaną wersję skryptu O_o Tync. Musiałem zrobić te mody dla OS X Lion i nie jest to idealne, ponieważ skrypt czasami kończy się, zanim zrobi to zapakowane polecenie. Dodałem sen, ale jestem pewien, że jest lepszy sposób.
źródło
To rozwiązanie działało dla mnie: https://superuser.com/questions/28869/immed natychmiast-tell-which-output-was-sent-to-stderr
Umieściłem tę funkcję w moim
.bashrc
lub.zshrc
:Następnie na przykład:
da mi czerwony wynik.
źródło
set -o pipefail;
wcześniej(eval
kod wyjścia przekierowania"
do eval, aby zachować spacje w argumentachużywając xargs i printf:
źródło
wersja korzystająca z fifos
źródło