Qu'est-ce que <() dans bash (et = () dans zsh)?


36

Je suis assez à l'aise avec bash, mais récemment je me suis retrouvé dans une substitution que je ne connaissais pas.

Qu'y a-t-il exactement <(<command>)dans bash? Comment se compare-t-il au =(<command>)in zsh?

Je comprends que cela a quelque chose à voir avec les descripteurs de fichiers par défaut. Dans mon ordinateur

echo <()

renvoie /proc/self/fd/11, que j'ai découvert être une copie du script STDOUT, mais cela me semble encore assez déroutant.

Réponses:


52

C'est ce qu'on appelle la substitution de processus.

La <(list)syntaxe est prise en charge à la fois par bashet zsh. Il fournit un moyen de passer la sortie d'une commande ( list) à une autre commande lorsque l'utilisation d'un tube ( |) n'est pas possible. Par exemple, lorsqu'une commande ne prend tout simplement pas en charge l'entrée de STDINou que vous avez besoin de la sortie de plusieurs commandes:

diff <(ls dirA) <(ls dirB)

<(list)connecte la sortie de listavec un fichier dans /dev/fd, s'il est pris en charge par le système, sinon un canal nommé (FIFO) est utilisé (qui dépend également de la prise en charge par le système; aucun manuel ne dit ce qui se passe si les deux mécanismes ne sont pas pris en charge, probablement il abandonne avec une erreur). Le nom du fichier est ensuite passé en argument sur la ligne de commande.


zshprend également en charge =(list)comme remplacement possible pour <(list). Avec =(list)un fichier temporaire est utilisé à la place de fichier dans /dev/fdou un FIFO. Il peut être utilisé en remplacement <(list)si le programme doit chercher dans la sortie.

Selon le manuel ZSH, il pourrait également y avoir d'autres problèmes avec le <(list)fonctionnement:

Le =formulaire est utile car l' /dev/fdimplémentation du canal et celle du canal nommé <(...)présentent des inconvénients. Dans le premier cas, certains programmes peuvent fermer automatiquement le descripteur de fichier en question avant d'examiner le fichier sur la ligne de commande, en particulier si cela est nécessaire pour des raisons de sécurité, comme lorsque le programme exécute setuid. Dans le second cas, si le programme n'ouvre pas réellement le fichier, le sous-shell tentant de lire ou d'écrire dans le canal (dans une implémentation typique, différents systèmes d'exploitation peuvent avoir un comportement différent) se bloquera pour toujours et devra être tué explicitement . Dans les deux cas, le shell fournit en fait les informations à l'aide d'un canal, de sorte que les programmes qui s'attendent à lseek (voir la page de manuel lseek(2)) sur le fichier ne fonctionneront pas.


Cela m'a aidé à comprendre pourquoi MacOS pfctl -f <(echo "pf rules")dirait un mauvais descripteur de fichier. l'utilisation de zsh et = (echo "règles pf") fonctionne à la place.
johnnyB

9

Notez que c'est une réponse bash, pas zsh.

Il y a des cas dans bash où vous ne pouvez pas utiliser de tuyaux:

some_command | some_other_command

parce que les tuyaux introduisent des sous-coquilles pour chaque composant du pipeline, lorsque les sous-coquilles se terminent, tous les effets secondaires sur lesquels vous comptiez disparaissent. Par exemple, cet exemple artificiel:

cat file | while read line; do ((count++)); done
echo $count

affichera une ligne vierge, car la $countvariable n'existe pas dans le shell actuel.

Une substitution de processus bash vous permet d'éviter cette énigme en vous permettant de lire à partir de la sortie "some_command" comme vous le feriez dans un fichier

while read line; do ((count++)); done < <(cat file)
# ....................................1.2
echo $count   # the variable *does* exist in the current shell

(1) est une redirection d'entrée normale. (2) est le début de la <()syntaxe de substitution de processus.


2
= (cmdlist) dans zsh a presque le même effet que <(cmdlist) dans bash mais il crée (et supprime quand il est prêt) un fichier temporaire avec la sortie de cmdlist pour la redirection. C'est bon lorsque la recherche est potentiellement effectuée dans le programme. <(cmdlist) est également connu de zsh.
Gombai Sándor
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.