Indica immediatamente quale output è stato inviato a stderr


8

Quando si automatizza un'attività, è consigliabile testarla prima manualmente. Sarebbe utile, tuttavia, se tutti i dati che vanno a stderr fossero immediatamente riconoscibili come tali, e distinguibili dai dati che vanno a stdout, e avere tutti gli output insieme, quindi è ovvio quale sia la sequenza di eventi.

Un ultimo tocco sarebbe bello se, all'uscita dal programma, stampasse il suo codice di ritorno.

Tutte queste cose aiuterebbero nell'automazione. Sì, posso ripetere il codice di ritorno al termine di un programma e sì, posso reindirizzare stdout e stderr; quello che mi piacerebbe davvero che fosse una shell, uno script o un redirector facile da usare che mostra stdout in nero, mostra stderr interlacciato con esso in rosso e stampa il codice di uscita alla fine.

C'è una tale bestia? [Se è importante, sto usando Bash 3.2 su Mac OS X].


Aggiornamento : mi dispiace che sono passati mesi da quando ho visto questo. Ho escogitato un semplice script di test:

#!/usr/bin/env python
import sys

print "this is stdout"
print >> sys.stderr, "this is stderr"
print "this is stdout again"

Nei miei test (e probabilmente a causa del modo in cui le cose sono bufferizzate), rse e hilite mostrano tutto da stdout e poi tutto da stderr. Il metodo fifo ottiene l'ordine giusto ma sembra colorare tutto ciò che segue la linea stderr. ind si è lamentato delle mie linee stdin e stderr, e poi ha messo l'ultimo output di stderr.

La maggior parte di queste soluzioni sono realizzabili, in quanto non è atipico che solo l'ultimo output passi a stderr, ma sarebbe comunque bello avere qualcosa che funzioni leggermente meglio.


Se sei pigro (o hai le dita doloranti) come me, puoi prendere una subshell con le soluzioni seguenti (es. Rse zsh) e ora tutti i comandi colorano stderr.
pregiudizio

Risposte:


3

Puoi anche dare un'occhiata a stderred: https://github.com/sickill/stderred


Sfortunatamente, stderred rompe "open" e "mvim" per gli utenti Mac come l'OP.
AlcubierreDrive il

Funziona molto bene e ottiene l'ordine di uscita nel modo corretto grazie al modo in cui funziona. Impostalo una volta, accendilo nel tuo profilo e otterrai messaggi rossi ogni volta che si scrive stderr.
Clinton Blackmore,


9

Ho appena ideato un metodo folle che coinvolge FIFO.

$ mkfifo foo
$ grep --color . foo &
$ your_command 2>foo

Se desideri che l'output stderr sia separato, puoi aprire due shell separate ed eseguire " grep --color . foo" in uno senza il &, quindi eseguire il comando nell'altro (sempre con il 2>foo). Otterrai lo stderr in grepquello e lo stdout in quello principale.

Questo funziona perché l'output di stderr viene instradato attraverso FIFO in grep --color, il cui colore predefinito è rosso (almeno per me). Al termine, solo rmFIFO ( rm foo).

Avvertenza : non sono davvero sicuro di come gestirà l'ordine di output, dovrai provarlo.


È piuttosto elegante.
Clinton Blackmore,

7

Sì, questo è possibile. Guarda la sezione "Rendi STDERR rosso" su questo sito per un esempio funzionante.

Il codice di base è questo

# 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
}

Una breve spiegazione è fornita nella funzione stessa. Ciò che fa è spostare STDOUT e STDERR, quindi sed ottiene STDERR in 1, lo colora e poi lo scambia. Pensa al flusso di file 3 come una variabile temporanea qui.

La chiamata è piuttosto semplice

rse commands

Tuttavia, alcune invocazioni non funzioneranno come previsto; le avvertenze sono fornite nella pagina collegata.

A proposito, penso che sia anche possibile trovare una soluzione del modulo

commands | rse 

dove rse colorerà l'output.

Ho anche trovato questo progetto di hilite che sembra fare questo. Non l'ho provato, ma potrebbe essere quello che stai cercando.

hilite è una piccola utility che esegue il comando specificato, evidenziando qualsiasi cosa stampata su stderr. È progettato principalmente per l'uso con build, per far risaltare avvisi ed errori come un cliché dolente.

Altri progetti correlati:


rse e hilite sono abbastanza vicine a ciò che voglio.
Clinton Blackmore,

1

Un altro programma è ind:

http: // www.habets.pp.se/synscan/programs.php?prog=ind (devi assemblare tu stesso il collegamento ipertestuale, non ho abbastanza punti per più di uno per risposta). C'è uno screenshot e persino uno screencast lì.

Esegue il sottoprocesso in un pty, che probabilmente gli altri non fanno. Questo può importare dove l'ordine conta (spesso succede), poiché stderr viene immediatamente scaricato nei terminali e stdout è completamente bufferato quando non è un valore.

Per una spiegazione completa, vedere questo: http://blog.habets.pp.se/2008/06/Buffering-in-pipes

Inoltre, ind funziona con programmi interattivi e personaggi di controllo. Bash funziona come al solito quando viene avviato con "ind bash -i".

Questo potrebbe funzionare per darti colori preservando Ctrl-P et.al.

ind -P $(echo -ne '\033[31;1m') -p $(echo -ne '\033[0m') bash -i

1

Ecco molte risposte per evidenziare l'output stderr. Posso solo aggiungerne uno abbastanza semplice, in una riga, che si allega al comando:

command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m"; done)

Ma devi aggiungere questo dopo ogni comando.

Personalmente, come la possibilità menzionata da @nagul, la funzione rse è stata aggiunta a bashrc.

Ma voglio aggiungere la soluzione per la stampa del codice di uscita. È possibile aggiungere questo valore all'inizio della riga del prompt di bash:

hostname$ command
  Some error occurred. Returned exit code.
EC hostname$

Dove EC è il codice di uscita del comando.

L'ho impostato in modo che quando il codice di uscita è 0, non verrà stampato, ma qualsiasi altro valore viene stampato prima del prossimo prompt in colore rosso.

L'intero trucco è fatto in ~ / .bashrc:

my_prompt() {
 EXITSTATUS="$?"
 RED="\[\033[1;31m\]"
 OFF="\[\033[m\]"

PROMPT="${debian_chroot:+($debian_chroot)}\h \$ "

if [ "${EXITSTATUS}" -eq 0 ]; then
   PS1="${PROMPT}"
else
   PS1="${RED}$EXITSTATUS${OFF} ${PROMPT}"
fi
}

PROMPT_COMMAND=my_prompt

La riga di comando è definita per impostazione predefinita dalla variabile PS1. Copia tutto ciò che hai qui nella variabile PROMPT e quindi crea la variabile PS1 con o senza codice di uscita.

Bash mostrerà le informazioni nella variabile PS1 nel prompt.


Questo è esattamente quello che stavo cercando, grazie!
Dylon,

1

c'è annotate-outputun'utilità ( devscriptspacchetto Debian), se vuoi farlo senza colori

$ annotate-output /tmp/test.py    
14:24:57 I: Started /tmp/test.py
14:24:57 E: this is stderr
14:24:57 O: this is stdout
14:24:57 O: this is stdout again
14:24:57 I: Finished with exitcode 0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.