A quale stream scrive Bash?


8

Sto cercando di reindirizzare tutto l'output da bash (prompt, input dell'utente, risultati) a un file

Esempio:

/bin/bash > file.txt 2>&1

Ho pensato che avrebbe funzionato, ma non sto ricevendo il prompt. Qualcuno può dirmi cosa sto facendo di sbagliato?

Risposte:


9

Bash emette il prompt solo in modalità interattiva. Cioè viene normalmente inviato al terminale (/ dev / tty su Linux). Questo non è né / dev / stdout né / dev / stdin :)

Ora, non sono sicuro, ma posso immaginare che bash consentirà una modalità interattiva limitata quando non c'è un tty completamente funzionale. In tal caso, mi aspetto che il prompt venga scritto su stdout. Non l'ho provato.

Nice Proof Of Concept:

(for a in some set of words; do echo $a > /dev/tty; done) 2>&1 > /dev/null

produrrà solo 1..10 come se non ci fosse il reindirizzamento. Come il prompt, l'output viene inviato direttamente al terminale (che fallirà se non ce n'è uno)

SUGGERIMENTO: se vuoi che tutto sia raccolto, guarda


Aggiunti suggerimenti su come ottenere potenzialmente più output bash in una pipe
vedi il

seqè un comando esterno altamente non standard e non dovrebbe essere utilizzato in questo modo. Se stai usando bash, fai qualcosa di simile for x in {1..10}o for ((x=1; x<=10; x++))invece.
Chris Down,

@Chris: buon punto, grazie per il testa a testa
visto il

2

Per indurre basha pensare che sia in modalità interattiva (anche se stdoutnon viene inviato a un terminale) è possibile utilizzare il scriptcomando già menzionato .

(
exec 1> >(tee bashlog.txt) 2>&1
script -q /dev/null /bin/bash -l
)

# alternative without script command
(
# bash: no job control in this shell
exec 1> >(tee bashlog.txt) 2>&1
/bin/bash -il
)

2

Il modo più semplice per farlo sarebbe

bash -i >/tmp/logfile 2>&1

Bash scriverà tutto /tmp/logfilee continuerà a eseguire i comandi mentre li digiti, ma non verrà visualizzato nulla nel terminale. Puoi farlo uscire mentre esci dalla sessione del terminale - premendo Ctrl+ Do digitando exit.

Nota che se esegui la stessa cosa senza stderrreindirizzamento, avrai solo il messaggio di saluto registrato nel file, tutto il resto funzionerà nel tuo terminale corrente. Quindi la risposta alla tua domanda sullo stream a cui bash genera il suo prompt (e tutti i seguenti comandi) sembra essere: stderr .

Oh sì, e il -iparametro forza semplicemente bash a funzionare in modalità interattiva. Non ascoltare quelle persone - non hai bisogno di trucchi magici per farlo;)


+1 da utilizzare <sub>per formattare. Ho appena imparato qualcosa di nuovo oggi. : D
Chris K,

2

Il prompt è scritto su stderr come mostra truss (su Solaris qui):

$ truss -ft write -p 10501
10501:  write(2, " d", 1)               = 1
10501:  write(2, " a", 1)               = 1
10501:  write(2, " t", 1)               = 1
10501:  write(2, " e", 1)               = 1
10501:  write(2, "\n", 1)               = 1
10521:  write(1, " S a t u r d a y ,   S e".., 46)  = 46
10501:      Received signal #18, SIGCLD [caught]
10501:        siginfo: SIGCLD CLD_EXITED pid=10521 status=0x0000
10501:  write(2, " $  ", 2)             = 2
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.