Esiste una linea guida POSIX, GNU o di altro tipo ufficiale su dove stampare i rapporti sullo stato di avanzamento e le informazioni di registrazione (cose come "Doing foo; foo done")? Personalmente, tendo a scriverli su stderr in modo da poter reindirizzare stdout e ottenere solo l'output effettivo del programma. Di recente mi è stato detto che questa non è una buona pratica poiché i rapporti sullo stato di avanzamento non sono in realtà errori e solo i messaggi di errore dovrebbero essere stampati su stderr.
Entrambe le posizioni hanno senso e ovviamente puoi scegliere l'una o l'altra a seconda dei dettagli di ciò che stai facendo, ma vorrei sapere se esiste uno standard comunemente accettato per questo. Non sono stato in grado di trovare regole specifiche in POSIX, gli standard di codifica GNU o altri elenchi di buone pratiche ampiamente accettati.
Abbiamo alcune domande simili, ma non affrontano questo problema esatto:
-
Quando utilizzare il reindirizzamento a stderr negli script di shell:la risposta accettata suggerisce cosa tendo a fare, mantenere l'output finale del programma su stdout e qualsiasi altra cosa su stderr. Tuttavia, questa viene presentata solo come opinione di un utente, sebbene supportata da argomenti.
-
Il messaggio di utilizzo dovrebbe andare a stderr o stdout?:Questo è specifico per i messaggi di aiuto ma cita lo standard di codifica GNU. Questo è il genere di cose che sto cercando, ma non solo per i messaggi di aiuto.
Quindi, esistono regole ufficiali su dove stampare i rapporti sullo stato di avanzamento e altri messaggi informativi (che non fanno parte dell'output effettivo del programma)?
Risposta accettata:
Posix definisce così i flussi standard:
All'avvio del programma, tre flussi devono essere predefiniti e non devono essere aperti in modo esplicito:standard input (per la lettura dell'input convenzionale), output standard (per la scrittura di output convenzionale) e errore standard (per la scrittura dell'uscita diagnostica). Quando viene aperto, il flusso di errore standard non è completamente memorizzato nel buffer; i flussi di input standard e di output standard sono completamente bufferizzati se e solo se è possibile determinare che il flusso non fa riferimento a un dispositivo interattivo.
La libreria GNU C descrive i flussi standard in modo simile:
Variabile:FILE * Stdout
Il flusso di output standard, utilizzato per il normale output del programma.
Variabile:FILE * stderr
Il flusso di errore standard, utilizzato per i messaggi di errore e la diagnostica emessi dal programma.
Pertanto, le definizioni standard hanno poche indicazioni per l'utilizzo del flusso oltre a "output normale/convenzionale" e "output diagnostico/errore". In pratica, è comune reindirizzare uno o entrambi questi flussi a file e pipeline, dove gli indicatori di avanzamento saranno un problema. Alcuni sistemi addirittura monitorano stderr
per l'output e considerarlo un segno di problemi. Le informazioni sullo stato di avanzamento puramente ausiliarie sono quindi problematiche su entrambi i flussi.
Invece di inviare indicatori di avanzamento incondizionatamente a uno flusso standard, è importante riconoscere che l'output sui progressi è appropriato solo per interattivo flussi. Con questo in mente, consiglio di scrivere i contatori di avanzamento solo dopo aver verificato se lo stream è interattivo (ad esempio, con isatty()
) o quando esplicitamente abilitato da un'opzione della riga di comando. Ciò è particolarmente importante per i misuratori di avanzamento che si basano sul comportamento di aggiornamento del terminale per avere un senso, come le barre % di completamento.
Per alcuni messaggi di avanzamento molto semplici ("Starting X" … "Fatto con X") è più ragionevole includere l'output anche per flussi non interattivi. In tal caso, considera come gli utenti potrebbero interagire con gli stream, ad esempio effettuando ricerche con grep
o paging con less
o monitoraggio con tail -f
. Se ha senso vedere i messaggi di avanzamento in quei contesti, sarà molto più facile utilizzarli da stdout
.