Output diretto da un comando a un file incluso il comando originale, AND print in terminal

8

Durante l'esecuzione di alcuni test, ho bisogno di eseguire una serie di comandi. Sarebbe estremamente utile per me e mi avrebbe risparmiato un sacco di 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

Le persone hanno suggerito di usare il tee per me che fa un ottimo lavoro di stampa sul terminale e di inviare a un file ma non include il comando originale. Quello che mi piacerebbe finire è un file in cui la prima riga è il comando che ho eseguito, e quindi sotto quello è l'output dal 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.

Apprezzerei qualsiasi idea.

    
posta shaneoh 28.11.2017 - 10:13

3 risposte

13

Questo è tee che stai cercando.

ls -l | tee outfile

stampa l'output di ls -l su stdout (cioè il terminale) e lo salva nel file outfile allo stesso tempo. Ma : non scrive il nome del comando né su stdout né sul file. Per farlo, basta echo del nome del comando prima di eseguire il comando e inserisci entrambe le uscite in tee :

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

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

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

Dopodiché puoi solo eseguire

both "ls -l"

per ottenere il risultato desiderato. Metti la funzione nel tuo ~/.bashrc per averla definita in ogni nuovo terminale. Sostituisci outfile con per poter specificare il file di output con ad es. both "ls -l" output invece di scrivere su outfile ogni volta. Se non vuoi che il file di output venga sovrascritto, ma piuttosto aggiungilo ad esso, aggiungi l'opzione -a a tee .

    
risposta data dessert 28.11.2017 - 10:30
8

Potresti utilizzare il comando script che creerà un file dattiloscritto di tutto ciò che viene stampato sul tuo terminale. Crea una shell biforcuta e registrerà tutto fino alla chiusura della 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 I cat my_output ottengo lo stesso risultato:

$ 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
    
risposta data AJefferiss 28.11.2017 - 10:49
5

Puoi 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 anche l'effetto del comando set qui sotto a questa sotto-shell.

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

  • 2>&1 reindirizza lo stream 2 (errore standard) allo stream 1 (output standard).

  • | reindirizza il flusso di output standard del comando left al flusso di input standard del comando right.

  • tee FILE copia il flusso di input standard nel file FILE e nell'output standard.

Se la sequenza di comandi è già in un file di script, sarebbe più sensato eseguirla in questo modo:

bash -x /path/to/script args... 2>&1 | tee output.log
    
risposta data David Foerster 28.11.2017 - 13:53

Leggi altre domande sui tag