Disons que j'ai trop de programmes a
et b
que je peux exécuter avec ./a
et ./b
.
Est-il possible de différencier leurs sorties sans d'abord écrire dans des fichiers temporaires?
Utilisez <(command)
pour passer la sortie d'une commande à un autre programme comme s'il s'agissait d'un nom de fichier. Bash redirige la sortie du programme vers un tube et transmet un nom de fichier comme /dev/fd/63
À la commande externe.
diff <(./a) <(./b)
De même, vous pouvez utiliser >(command)
si vous voulez diriger quelque chose into une commande.
Cela s'appelle "Substitution de processus" dans la page de manuel de Bash.
En ajoutant aux deux réponses, si vous voulez voir une comparaison côte à côte, utilisez vimdiff
:
vimdiff <(./a) <(./b)
Quelque chose comme ça:
Une option serait d'utiliser canaux nommés (FIFO) :
mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo
... mais la solution de John Kugelman est beaucoup plus propre.
Pour toute personne curieuse, voici comment effectuer la substitution de processus en utilisant Fish Shell :
Bash:
diff <(./a) <(./b)
Poisson:
diff (./a | psub) (./b | psub)
Malheureusement, l'implémentation dans le poisson est actuellement déficiente ; fish suspendra ou utilisera un fichier temporaire sur le disque. Vous ne pouvez pas non plus utiliser psub pour la sortie de votre commande.
Ajoutant un peu plus aux réponses déjà bonnes (m'a aidé!):
La commande docker
renvoie son aide à STD_ERR
(C'est-à-dire le descripteur de fichier 2)
Je voulais voir si docker attach
Et docker attach --help
Donnaient la même sortie
$ docker attach
$ docker attach --help
Après avoir tapé ces deux commandes, j'ai fait ce qui suit:
$ diff <(!-2 2>&1) <(!! 2>&1)
!! est identique à! -1, ce qui signifie exécuter la commande 1 avant celle-ci - la dernière commande
! -2 signifie exécuter la commande deux avant celle-ci
2> & 1 signifie envoyer la sortie file_descriptor 2 (STD_ERR) au même endroit que la sortie file_descriptor 1 (STD_OUT)
J'espère que cela vous a été d'une certaine utilité.
Pour zsh, l'utilisation de =(command)
crée automatiquement un fichier temporaire et remplace =(command)
par le chemin du fichier lui-même. Avec la substitution de processus normale, $(command)
est remplacée par sortie de la commande.
Cette fonctionnalité zsh est très utile et peut être utilisée comme telle pour comparer la sortie de deux commandes à l'aide d'un outil de comparaison, par exemple Beyond Compare:
bcomp =(ulimit -Sa | sort) =(ulimit -Ha | sort)
Pour Beyond Compare, notez que vous devez utiliser bcomp
pour ce qui précède (au lieu de bcompare
) car bcomp
lance la comparaison et attend pour qu'il se termine. Si vous utilisez bcompare
, cela lance la comparaison et se ferme immédiatement à cause de quoi les fichiers temporaires créés pour stocker la sortie des commandes disparaissent.
En savoir plus ici: http://zsh.sourceforge.net/Intro/intro_7.html
Notez également ceci:
Notez que le Shell crée un fichier temporaire et le supprime lorsque la commande est terminée.
et ce qui est la différence entre $(...)
et =(...)
:
Si vous lisez la page de manuel de zsh, vous remarquerez peut-être que <(...) est une autre forme de substitution de processus similaire à = (...). Il y a une différence importante entre les deux. Dans le cas <(...), le Shell crée un canal nommé (FIFO) au lieu d'un fichier. C'est mieux, car cela ne remplit pas le système de fichiers; mais cela ne fonctionne pas dans tous les cas. En fait, si nous avions remplacé = (...) par <(...) dans les exemples ci-dessus, ils auraient tous cessé de fonctionner sauf fgrep -f <(...). Vous ne pouvez pas modifier un canal ou l'ouvrir en tant que dossier de messagerie; fgrep, cependant, n'a aucun problème avec la lecture d'une liste de mots dans un pipe. Vous vous demandez peut-être pourquoi la barre diff <(foo) ne fonctionne pas, car foo | diff - bar œuvres; c'est parce que diff crée un fichier temporaire s'il remarque que l'un de ses arguments est -, puis copie son entrée standard dans le fichier temporaire.