C'è un modo per fare in modo che bash mostri i messaggi stderr in rosso?
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
funziona con bash e zsh. Non è possibile aggiungere questo come risposta reputazione b / c.
C'è un modo per fare in modo che bash mostri i messaggi stderr in rosso?
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
funziona con bash e zsh. Non è possibile aggiungere questo come risposta reputazione b / c.
Risposte:
command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)
>&2
subito prima ; done)
, l'output destinato a stderr viene effettivamente scritto su stderr. È utile se vuoi catturare l'output normale del programma.
tput
, ed è leggermente più leggibile secondo me:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
IFS= read -r line
dovrebbe aiutare ma non lo fa. Non so perché.
Metodo 1: utilizzare la sostituzione del processo:
command 2> >(sed $'s,.*,\e[31m&\e[m,'>&2)
Metodo 2: creare una funzione in uno script bash:
color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1
Usalo in questo modo:
$ color command
Entrambi i metodi mostreranno i comandi stderr
in rosso.
Continua a leggere per una spiegazione di come funziona il metodo 2. Ci sono alcune caratteristiche interessanti dimostrate da questo comando.
color()...
- Crea una funzione bash chiamata color.set -o pipefail
- Questa è un'opzione shell che preserva il codice di ritorno dell'errore di un comando il cui output viene reindirizzato in un altro comando. Questo viene fatto in una subshell, creata dalle parentesi, in modo da non modificare l'opzione pipefail nella shell esterna. "$@"
- Esegue gli argomenti per la funzione come nuovo comando. "$@"
è equivalente a"$1" "$2" ...
2>&1
- Reindirizza il stderr
comando in stdout
modo che diventi sed
's stdin
.>&3
- Abbreviazione di 1>&3
, reindirizza stdout
a un nuovo descrittore di file temporaneo 3
. 3
viene reindirizzato in un stdout
secondo momento.sed ...
- A causa dei reindirizzamenti sopra, sed
's stdin
è il stderr
comando eseguito. La sua funzione è di circondare ogni riga con codici colore.$'...'
Un costrutto bash che gli fa capire i caratteri con escape backslash.*
- Corrisponde all'intera riga.\e[31m
- La sequenza di escape ANSI che fa diventare rossi i seguenti caratteri&
- Il sed
carattere di sostituzione che si espande all'intera stringa corrispondente (l'intera riga in questo caso).\e[m
- La sequenza di escape ANSI che reimposta il colore.>&2
- Stenografia per 1>&2
, questo reindirizza sed
's stdout
a stderr
.3>&1
- Reindirizza 3
nuovamente il descrittore di file temporaneo in stdout
.zsh
?
zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
Puoi anche dare un'occhiata a stderred: https://github.com/sickill/stderred
.bashrc
). Grazie comunque!
Il modo bash di rendere permanentemente rosso stderr sta usando 'exec' per reindirizzare i flussi. Aggiungi quanto segue al tuo 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;'
Ho precedentemente pubblicato su questo: Come impostare il colore del carattere per STDOUT e STDERR
source ~/.bashrc
due volte con questo, il mio terminale sostanzialmente si blocca.
Ho realizzato una sceneggiatura avvolgente che implementa la risposta di Balázs Pozsár in modo puro. Salvalo nei comandi $ PATH e prefisso per colorarne l'output.
#! / Bin / bash if [$ 1 == "--help"]; poi echo "Esegue un comando e colora tutti gli errori occorsi" echo "Esempio:` basename $ {0} `wget ..." echo "(c) o_O Tync, ICQ # 1227-700, divertiti!" uscita 0 fi # File temporaneo per rilevare tutti gli errori TMP_ERRS = $ (mktemp) # Esegui comando "$ @" 2>> (mentre leggi la riga; do echo -e "\ e [01; 31m $ line \ e [0m" | tee --append $ TMP_ERRS; done) EXIT_CODE = $? # Visualizza di nuovo tutti gli errori if [-s "$ TMP_ERRS"]; poi echo -e "\ n \ n \ n \ e [01; 31m === ERRORI === \ e [0m" cat $ TMP_ERRS fi rm -f $ TMP_ERRS # Finire uscita $ EXIT_CODE
Puoi usare una funzione come questa
#!/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
Aggiungo> & 2 per stampare su stderr
Ho una versione leggermente modificata della sceneggiatura di O_o Tync. Avevo bisogno di creare queste mod per OS X Lion e non è perfetto perché lo script a volte si completa prima del comando wrapping. Ho aggiunto un sonno ma sono sicuro che c'è un modo migliore.
#!/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
Questa soluzione ha funzionato per me: https://superuser.com/questions/28869/immediately-tell-which-output-was-sent-to-stderr
Ho inserito questa funzione nel mio .bashrc
o .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
}
Quindi ad esempio:
$ rse cat non_existing_file.txt
mi darà un risultato rosso.
set -o pipefail;
prima (eval
per il codice di uscita di reindirizzamento
"
to eval per preservare gli spazi negli argomenti
usando xargs e printf:
command 2> >(xargs -0 printf "\e[31m%s\e[m" >&2)