In che modo i programmi escono altrove rispetto a STDOUT / STDERR? Come evitarlo?


15

Apparentemente non conosco tutte le destinazioni di output disponibili per l'uso. Conosco stdout( &1) e stderr( &2). Tuttavia, dopo aver reindirizzato entrambi i descrittori, a volte ottengo ancora un output nella mia console!

L'esempio più semplice che mi viene in mente è GNU Parallel; Ogni volta che lo uso, vedo un avviso di citazione. Anche quando lo faccio &2>1 > file, vedo ancora l'avviso.

E lo stesso vale per emerge: quando corro emergendo e ci sono alcuni problemi, alcune informazioni non vengono stampate stdoutstdin, dal momento che le reindirizzo e continuano a passare.

Per lo più risolvo questi problemi usando script, ma mi chiedo ancora cosa sta causando questo problema.


1
Fornisci un esempio completo .
Kusalananda


8
Non li otterrai tutti . Uno script può sempre scrivere /dev/tty.
Satō Katsura,

1
Per quanto riguarda GNU parallel: mkdir ~/.parallel; touch ~/.parallel/will-citedisabiliterà il fastidioso messaggio. In alternativa, cerca altre implementazioni di parallel.
Satō Katsura,

2
@OleTange Perché non è un problema, sto chiedendo perché sta succedendo qualcosa e sto usando parallelcome esempio.
Matthew Rock

Risposte:


40

La sintassi che hai usato è sbagliata.

cmd &2>1 >file

sarà suddiviso come

cmd &
2>1 >file

Questo sarà:

  1. Esegui cmdcome processo in background senza reindirizzamenti
  2. In un processo separato (senza un comando!) Verrà reindirizzato stderra un file chiamato letteralmente 1e reindirizzato stdoutafile

La sintassi che desideri è:

cmd >file 2>&1

L'ordine delle operazioni è importante. Questo sarà:

  1. Reindirizza stdoutafile
  2. Reindirizzare stderra &1- cioè lo stesso filehandle distdout

Il risultato è che entrambi stderre stdoutverrà reindirizzato al file.

In bash, una semplice sintassi non standard (e quindi non lo consiglio, per motivi di portabilità) cmd &> filefa la stessa cosa.


Bene grazie. L'altro problema potrebbe essere /dev/tty, ma speriamo che ciò non accada troppo spesso (se non del tutto).
Matthew Rock

5
Se hai il atcomando sul tuo computer e disponi dei privilegi per usarlo, puoi eseguire il comando tramite at now. Vedi la manpage per i dettagli. Questo eseguirà il comando tramite un meccanismo di processo batch e il processo non avrà mai un tty su cui scrivere. Ma, in generale, non mi preoccuperei di questo caso limite. Solitamente verranno utilizzati solo i processi che richiedono interazione e deliberatamente devono mostrare cose agli utenti nonostante il reindirizzamento /dev/tty.
Stephen Harris,

stato lì, fatto quello
davidbak il

10

Ci sono due problemi

Il primo è che l'ordine conta, il secondo è /dev/tty.

Usiamo questo script come uno script di esempio da cui vogliamo catturare l'output di:

test.sh:

#!/bin/bash

echo dada
echo edada 1>&2
echo ttdada >/dev/tty

Ora vediamo gli output dei comandi:

./testmyscript.sh 2>&1 >/dev/null:

edada
ttdada

Poiché l'ordine di valutazione va da sinistra a destra, per prima cosa otteniamo "il reindirizzamento stderrverso qualsiasi destinazione stdout(quindi, output della console)". Quindi otteniamo il "reindirizzamento stdouta /dev/null. Finiamo con una situazione del genere:

stdout-> /dev/null stderr-> console

Quindi abbiamo capito bene:

./testmyscript.sh >/dev/null 2>&1

E otteniamo:

ttdada.

Ora facciamo "Reindirizza stdouta /dev/null", e quindi "Reindirizza stderr a dove sta puntando stdout" (quindi, /dev/null). Evviva!

Tuttavia, abbiamo ancora un problema; il programma stampa su /dev/tty. Ora non so come risolvere questo tipo di comportamento, quindi molto probabilmente ne avrai bisogno script, ma spero che questo comportamento non accada troppo spesso.

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.