Sortie directe d'une commande vers un fichier comprenant la commande d'origine ET impression dans le terminal

8

Lors de l'exécution de certains tests, je dois exécuter une série de commandes. Cela me serait extrêmement utile et me ferait gagner beaucoup de temps s'il y avait un moyen de faire toutes ces choses:

  • Exécutez la commande que je dois exécuter
  • Redirige toutes les sorties de la commande vers un fichier spécifié
  • Inclure la commande d'origine dans le fichier spécifié
  • Imprimer la sortie de la commande d'origine dans le terminal

Les gens m'ont suggéré d'utiliser tee pour moi qui fait un excellent travail d'impression sur le terminal ainsi que l'envoi dans un fichier mais n'inclut pas la commande d'origine. Ce que j'aimerais finir, c'est un fichier où la première ligne est la commande que j'ai exécutée, puis en dessous la sortie de la commande.

Quelqu'un a suggéré ceci:

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

Mais cela n'imprime pas la sortie dans le terminal ou n'inclut pas la commande d'origine dans le fichier.

J'apprécierais toutes les idées.

shaneoh
la source
2
Presque double de askubuntu.com/q/688498/295286 .
Sergiy Kolodyazhnyy
Je n'ai pas trouvé cela dans ma recherche - pas exactement la même chose, mais cela m'aurait probablement conduit à la réponse.
shaneoh
oui, et c'est pourquoi j'ai dit presque le double. Mais pour être parfaitement honnête avec mon avis, vous pouvez prendre presque n'importe quelle solution à partir de là et l'utiliser avec des tuyaux tee.
Sergiy Kolodyazhnyy

Réponses:

14

C'est ce teeque vous recherchez.

ls -l | tee outfile

imprime la sortie de ls -lstdout (c'est-à-dire le terminal) et l'enregistre en outfilemême temps dans le fichier . Mais : Il n'écrit le nom de la commande ni sur stdout ni dans le fichier. Pour y parvenir, il suffit de donner echole nom de la commande avant d'exécuter la commande et de diriger les deux sorties vers tee:

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

C'est lourd à taper, alors pourquoi ne pas définir une fonction?

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

Après cela, vous pouvez simplement exécuter

both ls -l

pour obtenir le résultat souhaité. Mettez la fonction dans votre ~/.bashrcpour la définir dans chaque nouveau terminal.

Si vous voulez pouvoir spécifier le fichier de sortie comme premier argument comme dans

both output ls -l

au lieu de cela, faites-le:

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

Si vous ne voulez pas que le fichier de sortie soit écrasé mais plutôt y être ajouté, ajoutez l' -aoption à tee.

dessert
la source
9

Vous pouvez utiliser la scriptcommande qui crée un fichier dactylographié de tout ce qui est imprimé sur votre terminal. Il crée un shell fourchu et enregistrera tout jusqu'à ce que ce shell soit quitté.

$ 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

Alors si je cat my_outputreçois la même sortie:

$ 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
AJefferiss
la source
6

Vous pouvez utiliser la fonction de débogage du shell avec tee:

( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
  • ( ... )démarre un sous-shell qui vous permet de «collecter» les flux de sortie de toutes les commandes exécutées dans le sous-shell. Il contient également l'effet de la setcommande ci-dessous sur ce sous-shell.

  • set -xactive l' xoption shell qui imprime toutes les commandes que le shell exécute dans le flux d'erreur standard avant de les exécuter.

  • 2>&1 redirige le flux 2 (erreur standard) vers le flux 1 (sortie standard).

  • | redirige le flux de sortie standard de la commande de gauche vers le flux d'entrée standard de la commande de droite.

  • tee FILEcopie le flux d'entrée standard dans le fichier FILEet sur la sortie standard.

Si votre séquence de commandes est déjà dans un fichier de script, il serait plus logique de l'exécuter comme ceci:

bash -x /path/to/script args... 2>&1 | tee output.log
David Foerster
la source