Czy istnieje sposób, aby wyświetlać komunikaty stderr bash w kolorze czerwonym?
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
działa na bash i zsh. Nie można tego dodać jako reputacji b / c.
Czy istnieje sposób, aby wyświetlać komunikaty stderr bash w kolorze czerwonym?
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:
command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)
>&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:
command 2> >(sed $'s,.*,\e[31m&\e[m,'>&2)
Metoda 2: Utwórz funkcję w skrypcie bash:
color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1
Użyj tego w ten sposób:
$ color command
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
- Przekierowuje stderr
polecenie, aby stdout
stało się sed
's stdin
.>&3
- Skrótowo oznacza 1>&3
to przekierowanie stdout
do nowego tymczasowego deskryptora pliku 3
. 3
wraca stdout
później.sed ...
- Z powodu powyższych przekierowań, sed
„s stdin
jest stderr
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&
- Znak sed
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ótem 1>&2
, to przekierowuje sed
„s stdout
do stderr
.3>&1
- Przekierowuje deskryptor pliku tymczasowego z 3
powrotem do stdout
.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
.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:
exec 9>&2
exec 8> >(
while IFS='' read -r line || [ -n "$line" ]; do
echo -e "\033[31m${line}\033[0m"
done
)
function undirect(){ exec 2>&9; }
function redirect(){ exec 2>&8; }
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'
Wcześniej napisałem na ten temat: Jak ustawić kolor czcionki dla STDOUT i STDERR
source ~/.bashrc
dwa razy, mój terminal zasadniczo się zablokuje.
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
Możesz użyć takiej funkcji
#!/bin/sh
color() {
printf '\033[%sm%s\033[m\n' "$@"
# usage color "31;5" "string"
# 0 default
# 5 blink, 1 strong, 4 underlined
# fg: 31 red, 32 green, 33 yellow, 34 blue, 35 purple, 36 cyan, 37 white
# bg: 40 black, 41 red, 44 blue, 45 purple
}
string="Hello world!"
color '31;1' "$string" >&2
Dołączam> i 2, aby wydrukować na stderr
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/bash
if [ $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 0
fi
# 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 again
if [ -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
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
:
# 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
}
Następnie na przykład:
$ rse cat non_existing_file.txt
da mi czerwony wynik.
set -o pipefail;
wcześniej (eval
kod wyjścia przekierowania
"
do eval, aby zachować spacje w argumentach
używając xargs i printf:
command 2> >(xargs -0 printf "\e[31m%s\e[m" >&2)