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 ilstderrdel comando astdoutin modo che diventisedstdindi .>&3— Scorciatoia per1>&3, questo reindirizzastdouta un nuovo descrittore di file temporaneo3.3viene reinstradato instdoutpiù tardi.sed ...— A causa dei reindirizzamenti precedenti,sedstdindi è ilstderrdel 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&— Ilsedcarattere 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 reindirizzasedstdoutdi astderr.3>&1— Reindirizza il descrittore di file temporaneo3di 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.