Dans bash, appeler foo
afficherait toute sortie de cette commande sur la sortie standard.
L'appel de foo > output
redirigerait toute sortie de cette commande vers le fichier spécifié (dans ce cas, 'sortie').
Existe-t-il un moyen de rediriger la sortie vers un fichier et l'affiche sur stdout?
La commande que vous voulez s'appelle tee
:
foo | tee output.file
Par exemple, si vous ne vous souciez que de stdout:
ls -a | tee output.file
Si vous voulez inclure stderr, faites:
program [arguments...] 2>&1 | tee outfile
2>&1
redirige le canal 2 (erreur standard/stderr) vers le canal 1 (sortie standard/standard), de sorte que les deux soient écrits en tant que sortie standard Il est également dirigé vers le fichier de sortie donné à partir de la commande tee
.
De plus, si vous voulez ajouter dans le fichier journal, utilisez tee -a
comme:
program [arguments...] 2>&1 | tee -a outfile
$ program [arguments...] 2>&1 | tee outfile
2>&1
vide les flux stderr et stdout .tee outfile
prend le flux qu'il reçoit et l'écrit sur l'écran et dans le fichier "outfile".
C'est probablement ce que la plupart des gens recherchent. La situation probable est que certains programmes ou scripts travaillent dur depuis longtemps et produisent beaucoup de résultats. L'utilisateur veut vérifier périodiquement s'il y a progrès, mais veut aussi que la sortie soit écrite dans un fichier.
Le problème (en particulier lors du mélange de flux stdout et stderr) est qu’il faut compter sur les flux vidés par le programme. Si, par exemple, toutes les écritures sur stdout sont non vidées, mais que toutes les écritures sur stderr sont vidées, elles se retrouveront alors hors de l'ordre chronologique dans le fichier de sortie et à l'écran.
Il est également mauvais si le programme ne génère qu'une ou deux lignes toutes les quelques minutes pour signaler les progrès. Dans un tel cas, si la sortie n'était pas purgée par le programme, l'utilisateur ne verrait même aucune sortie à l'écran pendant des heures, car rien de cela ne serait poussé dans le tuyau pendant des heures.
Mise à jour: Le programme unbuffer
, qui fait partie du package expect
, résoudra le problème de mise en mémoire tampon. Cela provoquera l'écriture immédiate de stdout et stderr sur l'écran et le fichier et de les synchroniser lors de la combinaison et de la redirection vers tee
. Par exemple.:
$ unbuffer program [arguments...] 2>&1 | tee outfile
Quelque chose à ajouter ...
Le paquet unbuffer a des problèmes de support avec certains paquets sous Fedora et les versions unix redhat.
Mettre de côté les ennuis
Suivre a travaillé pour moi
bash myscript.sh 2>&1 | tee output.log
Merci ScDF & matthew vos contributions m'ont fait gagner beaucoup de temps ..
utiliser tail -f output
devrait fonctionner.
Réponse en prime depuis que ce cas d'utilisation m'a amené ici:
Dans le cas où vous devez le faire comme un autre utilisateur
echo "some output" | Sudo -u some_user tee /some/path/some_file
Notez que l'écho se produira comme vous et que l'écriture du fichier se produira comme "un_utilisateur" ce quePASfonctionnera si vous exécutez l'écho comme "un_utilisateur" et redirigez la sortie avec >> "un_fichier" parce que la redirection de fichier se fera comme vous.
Astuce: tee prend également en charge l'ajout de l'indicateur -a. Si vous devez remplacer une ligne d'un fichier par un autre utilisateur, vous pouvez exécuter sed en tant qu'utilisateur souhaité.
< command > |& tee filename
# Ceci créera un fichier "nom de fichier" avec le statut de la commande comme contenu. Si un fichier existe déjà, il supprimera le contenu existant et écrira le statut de la commande.
< command > | tee >> filename
# ceci ajoutera le statut au fichier mais n'imprimera pas le statut de la commande sur standard_output (screen).
Je veux imprimer quelque chose en utilisant "echo" à l'écran et ajouter les données en écho à un fichier
echo "hi there, Have to print this on screen and append to a file"
Vous pouvez le faire pour tout votre script en utilisant quelque chose comme ça au début de votre script:
#!/usr/bin/env bash
test x$1 = x$'\x00' && shift || { set -o pipefail ; ( exec 2>&1 ; $0 $'\x00' "$@" ) | tee mylogfile ; exit $? ; }
# do whaetever you want
Ceci redirige les sorties stderr et stdout vers le fichier mylogfile
et laisse tout aller sur stdout en même temps .
Il est utilisé des astuces stupides:
exec
sans commande pour configurer les redirections,tee
pour dupliquer les sorties,NUL
spécifié par la notation $'string'
spéciale bash) pour indiquer que le script est redémarré (aucun paramètre équivalent ne peut être utilisé par votre travail d'origine),pipefail
.Moche mais utile pour moi dans certaines situations.