Ecco una soluzione che combina alcune delle buone idee già presentate.
Crea una funzione in uno script bash:
color() ( set -o pipefail; "[email protected]" 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,' >&2 ) 3>&1
Usalo in questo modo:
$ color command -program -args
Mostrerà il stderr
del comando in rosso.
Continua a leggere per una spiegazione di come funziona. Ci sono alcune caratteristiche interessanti dimostrate da questo comando.
color()...
— Crea una funzione bash chiamata color.set -o pipefail
— Questa è un'opzione di shell che conserva 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."[email protected]"
— Esegue gli argomenti della funzione come nuovo comando."[email protected]"
equivale a"$1" "$2" ...
2>&1
— Reindirizza ilstderr
del comando astdout
in modo che diventised
stdin
di .>&3
— Scorciatoia per1>&3
, questo reindirizzastdout
a un nuovo descrittore di file temporaneo3
.3
viene reinstradato instdout
più tardi.sed ...
— A causa dei reindirizzamenti precedenti,sed
stdin
di è ilstderr
del comando eseguito. La sua funzione è quella 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 rende rossi i seguenti caratteri&
— Ilsed
carattere di sostituzione che si espande nell'intera stringa corrispondente (l'intera riga in questo caso).\e[m
— La sequenza di escape ANSI che reimposta il colore.>&2
— Scorciatoia per1>&2
, questo reindirizzased
stdout
di astderr
.3>&1
— Reindirizza il descrittore di file temporaneo3
di nuovo instdout
.
Ecco un'estensione dello stesso concetto che rende anche STDOUT green:
function stdred() (
set -o pipefail;
(
"[email protected]" 2>&1>&3 |
sed $'s,.*,\e[31m&\e[m,' >&2
) 3>&1 |
sed $'s,.*,\e[32m&\e[m,'
)
Puoi anche dare un'occhiata a stderred:https://github.com/sickill/stderred
Non riesco a vedere che ci sia un modo per l'emulatore di terminale di farlo.
L'interfaccia tra l'emulatore di terminale e la shell/app avviene tramite una pseudo-tty, dove l'emulatore di terminale si trova sul lato master e la shell/app sull'altro. La shell/app ha sia stdout che stderr collegati allo stesso pty, quindi quando l'emulatore di terminale legge dal pty l'output della shell/app non può più dire quale è stato scritto su stdout e quale su stderr.
Dovrai utilizzare una delle soluzioni che intercetta i dati tra l'applicazione e lo slave-pty e inserisce codici di escape per controllare l'output del terminale colo(u)r.