Pagina 1 di 2

Redirezione output

Inviato: gio 6 apr 2006, 13:02
da Pandorix
Hola :-)
La mia ennesima domanda verte in qualche modo sulla redirezione dell'output. Se per esempio lancio tcpdump > file.txt, l'output di tcpdump viene rediretto nel file senza che io possa vederlo, e se invece volessi anche vedere l'output oltre che a redirigerlo, potrei farlo?
Grazie

Inviato: gio 6 apr 2006, 13:20
da MAT
Boh, puoi provare con

Codice: Seleziona tutto

tcpdump > file.txt && cat file.txt

Inviato: gio 6 apr 2006, 14:20
da Pandorix
MAT ha scritto:Boh, puoi provare con

Codice: Seleziona tutto

tcpdump > file.txt && cat file.txt
Così funziona ma non come voglio io, mi fa il cat nel momento in cui interrompo il comando

Inviato: gio 6 apr 2006, 14:58
da sid77

Codice: Seleziona tutto

man bash
lo so, è lungo da leggere... prima:

Codice: Seleziona tutto

comando >file &
e poi

Codice: Seleziona tutto

tail -f file
btw: se vuoi solo vedere cosa fa tcpdump va bene usare ">" ma per salvare le sessioni ci sono opzioni apposita da utilizzare.

Inviato: gio 6 apr 2006, 15:10
da Eurialo
Ci sarebbe un metodo.. ma e' abbastanza bruttino... Consiste in:

Duplicare STDOUT in STDERR
Stampare a schermo STDOUT
Mettere in un file STDERR

Codice: Seleziona tutto

comando 1>&2 2>file
Ovviamente se in STDERR c'e' qualcosa, lo vedrai nel file mischiato a STDOUT e non lo vedrai a schermo!

Inviato: gio 6 apr 2006, 15:13
da Eurialo
Ops.. cross-posting con sid :)

Inviato: gio 6 apr 2006, 16:43
da sid77
Eurialo ha scritto:Ops.. cross-posting con sid :)
ehm, non proprio :D

la soluzione al problema di partenza è "usa & per mettere in bg il processo e poi lanciare un tail invece che usare && che ne attende l'uscita"

quello che dici tu è di giocare con gli STD*, manovra alquanto "acrobatica" quella proposta :D io di solito quando faccio un lavoro simile mi limito a

Codice: Seleziona tutto

comando &> file &
in modo da redirezionare STDERR e STDOUT in un colpo solo su file (usando "&>") e poi mettere tutto in bg con "&" finale

comunque la soluzione acrobatica a me piace un sacco :lol:

ciao

Inviato: gio 6 apr 2006, 22:59
da targzeta
Eurialo ha scritto: comando 1>&2 2>file
Questo comando ridirige soltanto l'stderr di 'comando' su 'file' (a proposito di leggere il man... :wink: ).

Il comando di sid77 è più interessante solo che lascia in foreground il comando tail mentre tcpdump starà in background.
Io ti consiglierei di fare il contrario, e cioé:

Codice: Seleziona tutto

tail -f file& comando > file
In questo modo è comando in foreground e quindi ci puoi lavorare normalmente.
Ricordati solo che quando esci da comando, tail è sempre in background....

Spina

Inviato: ven 7 apr 2006, 11:22
da Paoletta
spina ha scritto:
Eurialo ha scritto: comando 1>&2 2>file
Questo comando ridirige soltanto l'stderr di 'comando' su 'file' (a proposito di leggere il man... :wink: ).
già, meglio comando 2>file 1>&2 (la shell valuta da destra a sinistra)

EDIT:ovviamente da sinistra a destra...mica siamo in arabia! :lol:

Inviato: ven 7 apr 2006, 16:04
da targzeta
Paoletta ha scritto:già, meglio comando 2>file 1>&2 (la shell valuta da destra a sinistra)
Mi spiace contraddirti. Dal man di bash (perchè penso stiamo parlando tutti della bash):

Codice: Seleziona tutto

Redirections  are processed in the order they appear, from left to right.
comunque credo ci vogliano delle delucidazioni perchè il man della bash non è molto chiaro. Cerchiamo di capire che cosa fa la shell quando duplica gli stderr e stdout.
Userò indifferentemente stderr o 2, e stdout o 1.
Prima cosa da capire è che tutti i comandi eseguiti dalla shell sono suoi figli e, pertanto ne ereditano i file descriptor aperti.
Ora, che succede quando scriviamo ad esempio:

Codice: Seleziona tutto

ls > file
la shell:
1) apre file (creandolo o troncandolo a zero), prendendo quindi il suo file descriptor, supponiamo 3.
2) duplica il file descriptor 1 (lo stdout) con il nuovo file descriptor. Questo provoca la chiusura dello stdout e la sua duplicazione in 3. Ovvero, scrivere in 3 o scrivere in 1 è la stessa cosa.
3) (forse, ma dovrebbe essere buona norma) chiude il file descriptor 3.
4) lancia ls.
A questo punto quando ls scrive sullo stdout (1) scrive in realtà su file. Proprio perchè lo stdout è erediato dalla shell padre.

Un altro esempio è necessario:

Codice: Seleziona tutto

 ls 2>&1 > file
1) duplica lo stderr in stdout (2>&1). Questo provoca la chiusura dello stderr e la sua duplicazione nello stdout. In particolare, se lanciasse ora ls, che ls scriva in stderr o in stdout verrebbero intrambi stampati sullo stdout.
2) apre file prendondo il suo file descriptor, supponiamo ancora 3.
3) duplica il file descriptor 1 con 3 (> file). Ovvero, chiude il file descriptor 1 e lo riapre come 3.
4) lancia ls.
A questo punto succede una cosa simpatica. Se ls scrive sullo stderr, in realtà scrive sullo stdout. Se invece scrive sullo stdout, in realtà scrive sul file.
Proprio perchè la sequenza delle duplicazioni è avvenuta in questo modo: prima 2>&1 e poi 1>file.

Infine il comando:

Codice: Seleziona tutto

ls > file 2>&1
1) apre file. File descriptor 3.
2) duplica l'1 col 3. Chiude l'1 e lo riapre come 3.
3) duplica il 2 con l'1. Chiude il 2 e lo riapre come 1, che a sua volta era il 3.
4) (forse, ma buona norma) chiude il 3)
5) lancia ls.
A questo punto, sia l'1 che il 2 riferiscono al file, e quindi sia che ls scriva su 1 che su 2, in realtà scrive sul file.
Quindi come vedi la sequenza è importante.

Spero di aver chiarito qualche dubbio a qualcuno.
Spina

Inviato: ven 7 apr 2006, 16:22
da zzt
comunque, per ritornare alla domanda iniziale esiste un comando ad hoc: tee

Ad esempio:

Codice: Seleziona tutto

$dmesg | tee -a output.txt

Inviato: ven 7 apr 2006, 18:08
da Paoletta
spina ha scritto:
Paoletta ha scritto:già, meglio comando 2>file 1>&2 (la shell valuta da destra a sinistra)
Mi spiace contraddirti. Dal man di bash (perchè penso stiamo parlando tutti della bash):

Codice: Seleziona tutto

Redirections  are processed in the order they appear, from left to right.
comunque credo ci vogliano delle delucidazioni perchè il man della bash non è molto chiaro. Cerchiamo di capire che cosa fa la shell quando duplica gli stderr e stdout.
Userò indifferentemente stderr o 2, e stdout o 1.
Prima cosa da capire è che tutti i comandi eseguiti dalla shell sono suoi figli e, pertanto ne ereditano i file descriptor aperti.
Ora, che succede quando scriviamo ad esempio:

Codice: Seleziona tutto

ls > file
la shell:
1) apre file (creandolo o troncandolo a zero), prendendo quindi il suo file descriptor, supponiamo 3.
2) duplica il file descriptor 1 (lo stdout) con il nuovo file descriptor. Questo provoca la chiusura dello stdout e la sua duplicazione in 3. Ovvero, scrivere in 3 o scrivere in 1 è la stessa cosa.
3) (forse, ma dovrebbe essere buona norma) chiude il file descriptor 3.
4) lancia ls.
A questo punto quando ls scrive sullo stdout (1) scrive in realtà su file. Proprio perchè lo stdout è erediato dalla shell padre.

Un altro esempio è necessario:

Codice: Seleziona tutto

 ls 2>&1 > file
1) duplica lo stderr in stdout (2>&1). Questo provoca la chiusura dello stderr e la sua duplicazione nello stdout. In particolare, se lanciasse ora ls, che ls scriva in stderr o in stdout verrebbero intrambi stampati sullo stdout.
2) apre file prendondo il suo file descriptor, supponiamo ancora 3.
3) duplica il file descriptor 1 con 3 (> file). Ovvero, chiude il file descriptor 1 e lo riapre come 3.
4) lancia ls.
A questo punto succede una cosa simpatica. Se ls scrive sullo stderr, in realtà scrive sullo stdout. Se invece scrive sullo stdout, in realtà scrive sul file.
Proprio perchè la sequenza delle duplicazioni è avvenuta in questo modo: prima 2>&1 e poi 1>file.

Infine il comando:

Codice: Seleziona tutto

ls > file 2>&1
1) apre file. File descriptor 3.
2) duplica l'1 col 3. Chiude l'1 e lo riapre come 3.
3) duplica il 2 con l'1. Chiude il 2 e lo riapre come 1, che a sua volta era il 3.
4) (forse, ma buona norma) chiude il 3)
5) lancia ls.
A questo punto, sia l'1 che il 2 riferiscono al file, e quindi sia che ls scriva su 1 che su 2, in realtà scrive sul file.
Quindi come vedi la sequenza è importante.

Spero di aver chiarito qualche dubbio a qualcuno.
Spina

ooops, sorry, svista colossale: volevo dire da sinistra a destra...infatti il comando che ho suggerito è giusto! :oops: :P :P se fosse da destra a sinistra, non andrebbe...chiedo scusa per la svista!

Inviato: ven 7 apr 2006, 21:02
da Eurialo
Paoletta ha scritto: infatti il comando che ho suggerito è giusto! :oops: :P :P se fosse da destra a sinistra, non andrebbe...chiedo scusa per la svista!
Mi dispiace contraddirti, ma non "e' giusto" :) per provarlo ti basta eseguirlo: il tuo comando non stampa niente sul terminale!

Inviato: sab 8 apr 2006, 1:55
da targzeta
Eurialo ha scritto:per provarlo ti basta eseguirlo: il tuo comando non stampa niente sul terminale!
:cry: Righe e righe di spiegazioni sprecate :cry:

Lo sappiamo (almeno io lo so, ma sono quasi sicuro che lo sa anche Paoletta) che non stampa niente sul terminale, vuoi sapere perchè? leggi il mio precedente post!!!

Il comando di Paoletta è sintatticamente e semanticamente corretto, nel senso che è una forma corretta per ridirigere sia lo standard output che lo standard error su un file. Lascia stare che non fa quello chiesto da Pandorix, anche perchè meglio del comando tee illustratoci da zzt ....
Il tuo comando invece è sintatticamente ammissibile, ma semanticamente sbagliato, nel senso che non fà quello che hai detto tu, ovvero:
Duplicare STDOUT in STDERR
Stampare a schermo STDOUT
Mettere in un file STDERR

Vuoi sapere perchè? leggi il mio precedente post :lol:

Spina

Inviato: sab 8 apr 2006, 11:33
da Paoletta
confermo quel che ha detto Spina! :wink: