Uscita diretta da un comando a un file incluso il comando originale E stampa nel terminale


8

Quando eseguo alcuni test, devo eseguire una serie di comandi. Sarebbe estremamente utile per me e mi risparmierebbe molto tempo, se ci fosse un modo per fare tutte queste cose:

  • Esegui il comando che devo eseguire
  • Reindirizza tutto l'output dal comando a un file specificato
  • Includi il comando originale nel file specificato
  • Stampa l'output dal comando originale nel terminale

La gente mi ha suggerito di usare tee per me, che fa un ottimo lavoro di stampa su un terminale, oltre che di inviarlo a un file ma non include il comando originale. Quello che vorrei finire è un file in cui la prima riga è il comando che ho eseguito, quindi sotto quello è l'output del comando.

Qualcuno ha suggerito questo:

echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"

Ma questo non stampa l'output nel terminale o include il comando originale nel file.

Gradirei qualsiasi idea.



Non l'ho trovato nella mia ricerca, non esattamente lo stesso, ma probabilmente mi avrebbe portato alla risposta.
shaneoh,

sì, ed è per questo che ho detto quasi il duplicato. Ma per essere perfettamente onesto con la mia opinione, potresti prendere quasi qualsiasi soluzione da lì e utilizzarla con le tubazioni tee.
Sergiy Kolodyazhnyy,

Risposte:


14

Questo è quello teeche stai cercando.

ls -l | tee outfile

stampa l'output di ls -lstdout (ovvero il terminale) e lo salva nel file outfilecontemporaneamente. Ma : non scrive il nome del comando né su stdout né sul file. A tale scopo, basta solo echoil nome del comando prima di eseguire il comando e reindirizzare entrambi gli output a tee:

( echo "ls -l" && ls -l ) | tee outfile

È ingombrante da digitare, quindi perché non definire una funzione?

both(){ ( echo "$@" && "$@" ) | tee outfile ;}

Dopodiché puoi semplicemente correre

both ls -l

per ottenere il risultato desiderato. Inserisci la funzione nel tuo ~/.bashrcper averla definita in ogni nuovo terminale.

Se vuoi essere in grado di specificare il file di output come primo argomento come in

both output ls -l

invece fallo:

both(){ ( echo "${@:2}" && "${@:2}" ) | tee "$1" ;}

Se non si desidera sovrascrivere il file di output ma si aggiunge a esso, aggiungere l' -aopzione a tee.


9

È possibile utilizzare il scriptcomando che creerà un file dattiloscritto di tutto ciò che viene stampato sul terminale. Crea una shell biforcuta e registrerà tutto fino all'uscita da quella shell.

$ script my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
Script done on Tue 28 Nov 2017 09:46:27 AM UTC

Quindi se cat my_outputottengo lo stesso output:

$ cat my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
exit

Script done on Tue 28 Nov 2017 09:46:27 AM UTC

6

È possibile utilizzare la funzione di debug della shell insieme a tee:

( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
  • ( ... )avvia una sotto-shell che consente di "raccogliere" i flussi di output di tutti i comandi eseguiti all'interno della sotto-shell. Contiene inoltre l'effetto del setcomando seguente su questa sotto-shell.

  • set -xabilita l' xopzione shell che stampa tutti i comandi che la shell esegue sul flusso di errori standard prima di eseguirli.

  • 2>&1 reindirizza il flusso 2 (errore standard) al flusso 1 (output standard).

  • | reindirizza il flusso di output standard del comando sinistro al flusso di input standard del comando destro.

  • tee FILEcopia il flusso di input standard nel file FILEe nell'output standard.

Se la sequenza dei comandi si trova già in un file di script, avrebbe più senso eseguirla in questo modo:

bash -x /path/to/script args... 2>&1 | tee output.log
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.