En bash, l'appel foo
afficherait n'importe quelle sortie de cette commande sur la sortie standard.
L'appel 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 de l' afficher sur stdout?
foo > output
les données sont écrites sur stdout et stdout est le fichier nomméoutput
. Autrement dit, écrire dans le fichier, c'est écrire sur stdout. Vous demandez s'il est possible d'écrire à la fois sur stdout et sur le terminal.Réponses:
La commande que vous souhaitez est nommée
tee
:Par exemple, si vous ne vous souciez que de la sortie standard:
Si vous souhaitez inclure stderr, faites:
2>&1
redirige le canal 2 (stderr / erreur standard) vers le canal 1 (stdout / sortie standard), de sorte que les deux soient écrits comme stdout. Il est également dirigé vers le fichier de sortie donné à partir de latee
commande.De plus, si vous souhaitez ajouter au fichier journal, utilisez
tee -a
comme:la source
-a
argument ontee
pour ajouter du contenu àoutput.file
, au lieu de l'écraser:ls -lR / | tee -a output.file
$?
ensuite, il renverra le code d'état detee
, ce qui n'est probablement pas ce que vous voulez. Au lieu de cela, vous pouvez utiliser${PIPESTATUS[0]}
.2>&1
vide les flux stderr et stdout.tee outfile
prend le flux qu'il obtient et l'écrit à l'écran et dans le fichier "outfile".C'est probablement ce que la plupart des gens recherchent. La situation probable est qu'un programme ou un script travaille dur pendant longtemps et produit beaucoup de résultats. L'utilisateur souhaite vérifier régulièrement sa progression, mais souhaite également que la sortie soit écrite dans un fichier.
Le problème (en particulier lors du mélange des flux stdout et stderr) est qu'il y a une dépendance à l'égard des flux qui sont vidés par le programme. Si, par exemple, toutes les écritures sur stdout ne sont pas vidées, mais toutes les écritures sur stderr sont vidées, elles finiront par ordre chronologique dans le fichier de sortie et à l'écran.
C'est également mauvais si le programme ne produit que 1 ou 2 lignes toutes les quelques minutes pour signaler la progression. 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 aucune ne serait poussée à travers le tuyau pendant des heures.
Mise à jour: le programme
unbuffer
, qui fait partie duexpect
package, résoudra le problème de mise en mémoire tampon. Cela entraînera stdout et stderr à écrire sur l'écran et le fichier immédiatement et à les garder synchronisés lorsqu'ils sont combinés et redirigés verstee
. Par exemple:la source
$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
python
a une option intégrée-u
qui sort les tampons.Une autre façon qui fonctionne pour moi est,
comme indiqué dans le manuel de gnu bash
Exemple:
Pour plus d'informations, reportez-vous à la redirection
la source
$?
ensuite, il renverra le code d'état detee
, ce qui n'est probablement pas ce que vous voulez. Au lieu de cela, vous pouvez utiliser${PIPESTATUS[0]}
.Vous pouvez principalement utiliser la solution Zoredache , mais si vous ne voulez pas écraser le fichier de sortie, vous devez écrire tee avec l'option -a comme suit:
la source
Quelque chose à ajouter ...
Le paquet non tamponné a des problèmes de support avec certains paquets sous Fedora et les versions Unix de Redhat.
Mettre de côté les ennuis
La suite a fonctionné pour moi
la source
L'utilisation
tail -f output
devrait fonctionner.la source
Réponse bonus puisque ce cas d'utilisation m'a amené ici:
Dans le cas où vous devez le faire comme un autre utilisateur
Notez que l'écho se produira lorsque vous et l'écriture du fichier se produira en tant que "some_user" ce qui ne fonctionnera PAS si vous exécutez l'écho en tant que "some_user" et redirigez la sortie avec >> "some_file" car la redirection de fichier se produira comme toi.
Astuce: tee prend également en charge l'ajout avec l'indicateur -a, si vous devez remplacer une ligne dans un fichier en tant qu'autre utilisateur, vous pouvez exécuter sed en tant qu'utilisateur souhaité.
la source
< command > |& tee filename
# cela créera un fichier "filename" avec le statut de la commande en tant que contenu, si un fichier existe déjà, il supprimera le contenu existant et écrit le statut de la commande.< command > | tee >> filename
# ceci ajoutera le statut au fichier mais il n'imprimera pas le statut de la commande sur standard_output (écran).Je veux imprimer quelque chose en utilisant "echo" à l'écran et ajouter ces données en écho à un fichier
la source
Vous pouvez le faire pour l'ensemble de votre script en utilisant quelque chose comme ça au début de votre script:
Cela redirige les sorties stderr et stdout vers le fichier appelé
mylogfile
et laisse tout aller à stdout en même temps .Il est utilisé quelques astuces stupides:
exec
sans commande pour configurer les redirections,tee
pour dupliquer les sorties,NUL
caractère simple spécifié par la$'string'
notation bash spéciale) pour spécifier que le script est redémarré (aucun paramètre équivalent ne peut être utilisé par votre travail d'origine),pipefail
option.Moche mais utile pour moi dans certaines situations.
la source
tee est parfait pour cela, mais cela fera aussi le travail
la source
;
, la sortie serait très retardée lors d'une commande lente.