Il y a des commandes qui filtrent ou agissent en entrée, puis les transmettent en sortie, je pense en général stdout
, mais certaines commandes prennent juste le stdin
et font ce qu’elles font, sans rien sortir.
Je suis plus familier avec OS X et donc il y a deux qui me viennent immédiatement à l' esprit sont pbcopy
et pbpaste
- qui sont des moyens d'accès au presse - papiers du système.
Quoi qu'il en soit, je sais que si je veux prendre stdout et cracher la sortie pour aller aux deux stdout
et à un fichier, je peux utiliser la tee
commande. Et j'en connais un peu xargs
, mais je ne pense pas que ce soit ce que je recherche.
Je veux savoir comment je peux me séparer stdout
pour aller entre deux commandes (ou plus). Par exemple:
cat file.txt | stdout-split -c1 pbcopy -c2 grep -i errors
Il y a probablement un meilleur exemple que celui-là, mais je suis vraiment intéressé à savoir comment envoyer stdout à une commande qui ne le relayera pas et tout en évitant stdout
d'être "muet" - je ne vous demande pas comment créer cat
un fichier; grep
une partie de celui-ci et copiez-le dans le presse-papiers - les commandes spécifiques ne sont pas si importants.
Aussi - je ne demande pas comment envoyer cela dans un fichier et stdout
- cela peut être une question "en double" (désolé), mais j'en ai cherché et je n'ai trouvé que des questions similaires qui demandaient comment diviser entre stdout et un fichier - et les réponses à ces questions semblaient être tee
, ce qui, à mon avis, ne fonctionnera pas pour moi.
Enfin, vous pouvez vous demander "pourquoi ne pas simplement faire de pbcopy la dernière chose dans la chaîne de tubes?" et ma réponse est 1) si je veux l’utiliser et voir toujours la sortie dans la console? 2) Que faire si je veux utiliser deux commandes qui ne sortent pas stdout
après avoir traité l'entrée?
Oh, et encore une chose - je me rends compte que je pourrais utiliser tee
un tube nommé ( mkfifo
) mais j'espérais pouvoir le faire en ligne, de manière concise, sans configuration préalable :)
Réponses:
Vous pouvez utiliser
tee
et traiter la substitution pour cela:Cela enverra toute la sortie de
cat file.txt
àpbcopy
, et vous n'obtiendrez que le résultat degrep
sur votre console.Vous pouvez mettre plusieurs processus dans la
tee
pièce:la source
pbcopy
, mais mérite d’être mentionné en général: quels que soient les résultats de substitution de processus , le segment de conduite suivant voit également les résultats , après l’entrée initiale; Par exemple:seq 3 | tee >(cat -n) | cat -e
(cat -n
numérote les lignes d'entrée,cat -e
marque les nouvelles lignes avec$
; vous verrez qu'ilcat -e
est appliqué à la fois à l'entrée d'origine (la première) et à la sortie (ensuite)cat -n
). La sortie de plusieurs substitutions de processus arrivera dans un ordre non déterministe.>(
seul fonctionne dansbash
. Si vous essayez par exemple d’utilisersh
cela ne fonctionnera pas. Il est important de faire cet avis.dash
, qui agit commesh
sur Ubuntu, ne le supporte pas, et même Bash lui-même désactive la fonctionnalité quand elle est appeléesh
ou quandset -o posix
est en vigueur. Cependant, Bash n'est pas le seul à prendre en charge les substitutions de processus:ksh
et à leszsh
soutenir également (pas sûr des autres).bash
etksh
-zsh
apparemment, il n'envoie pas de sortie de substitutions de processus de sortie via le pipeline (sans doute, c'est préférable , car il ne pollue pas ce qui est envoyé au segment de pipeline suivant - bien que il imprime toujours ). Cependant, dans tous les shells mentionnés, ce n’est généralement pas une bonne idée d’avoir un seul pipeline dans lequel les sorties stdout et normales des substitutions de processus sont mélangées - l’ordre de sortie ne sera pas prévisible, de manière à ne faire surface que rarement ou avec de gros ensembles de données de sortie.Vous pouvez spécifier plusieurs noms de fichier
tee
et, en plus, la sortie standard peut être canalisée en une seule commande. Pour répartir la sortie sur plusieurs commandes, vous devez créer plusieurs canaux et spécifier chacun d'eux comme une sortie detee
. Il y a plusieurs moyens de le faire.Substitution de processus
Si votre shell est ksh93, bash ou zsh, vous pouvez utiliser la substitution de processus. C'est un moyen de transmettre un canal à une commande qui attend un nom de fichier. Le shell crée le canal et attribue un nom de fichier similaire
/dev/fd/3
à la commande. Le numéro correspond au descripteur de fichier auquel le canal est connecté. Certaines variantes unix ne supportent pas/dev/fd
; sur ceux-ci, un canal nommé est utilisé à la place (voir ci-dessous).Descripteurs de fichier
Dans n'importe quel shell POSIX, vous pouvez utiliser explicitement plusieurs descripteurs de fichier . Cela nécessite une variante unix compatible
/dev/fd
, car toutes les sorties sauf unetee
doivent être spécifiées par leur nom.Tuyaux nommés
La méthode la plus élémentaire et portable consiste à utiliser des canaux nommés . L'inconvénient est que vous devez trouver un répertoire accessible en écriture, créer les tuyaux et nettoyer par la suite.
la source
tee "$tmp_dir/f1" "$tmp_dir/f2" | command3
devrait sûrement êtrecommand3 | tee "$tmp_dir/f1" "$tmp_dir/f2"
, comme vous voulez stdout decommand3
sifflé àtee
, non? J'ai testé votre versiondash
ettee
bloqué dans l'attente d'une entrée indéfinie, mais le changement d'ordre a donné le résultat attendu.command
,command2
etcommand3
.<command> | bash -c 'tee >(command1) >(command2) | command3'
. Cela m'a aidé dans mon cas.Il suffit de jouer avec la substitution de processus.
grep
sont deux fichiers binaires qui ont la même sortiemycommand_exec
que leur entrée spécifique au processus.la source
Si vous utilisez
zsh
alors vous pouvez profiter de la puissance de laMULTIOS
fonctionnalité, c'est-à-dire vous débarrassertee
complètement de la commande:va simplement écrire la sortie de
uname
deux fichiers différents:file1
etfile2
, ce qui est équivalent àuname | tee file1 >file2
De même la redirection des entrées standard
est équivalent à
cat file1 file2 | wc -l
(veuillez noter qu'il ne s'agit pas de la même chose quewc -l file1 file2
, le dernier compte le nombre de lignes dans chaque fichier séparément).Bien sûr, vous pouvez également utiliser
MULTIOS
pour rediriger la sortie non vers des fichiers, mais vers d'autres processus, en utilisant la substitution de processus, par exemple:la source
MULTIOS
est une option activée par défaut (et pouvant être désactivée avecunsetopt MULTIOS
).Pour une sortie raisonnablement petite produite par une commande, nous pouvons rediriger la sortie vers un fichier temporaire et envoyer ce fichier temporaire à des commandes en boucle. Cela peut être utile lorsque l’ordre des commandes exécutées est important.
Le script suivant, par exemple, pourrait le faire:
Test exécuté sur Ubuntu 16.04 avec
/bin/sh
commedash
shell:la source
Capturez la commande
STDOUT
avec une variable et réutilisez-la autant de fois que vous le souhaitez:Si vous avez également besoin de capturer
STDERR
, utilisez2>&1
à la fin de la commande, comme suit:la source
Cela peut être utile: http://www.spinellis.gr/sw/dgsh/ (shell graphique dirigé) Ressemble à un remplacement bash supportant une syntaxe plus simple pour les commandes "multipipe".
la source
Voici une solution partielle rapide, compatible avec tout shell, y compris
busybox
.Le problème plus étroit qu’il résout est le suivant: imprimez le
stdout
fichier complet sur une console et filtrez-le sur une autre, sans fichiers temporaires ni canaux nommés.tty
. Supposons/dev/pty/2
.the_program | tee /dev/pty/2 | grep ImportantLog:
Vous obtenez un journal complet et un journal filtré.
la source