C'est ce qu'on appelle la substitution de processus.
Le <(list)
la syntaxe est prise en charge par les deux, bash
et zsh
. Il fournit un moyen de transmettre la sortie d'une commande (list
) à une autre commande lors de 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 STDIN
ou vous avez besoin de la sortie de plusieurs commandes :
diff <(ls dirA) <(ls dirB)
<(list)
connecte la sortie de list
avec un fichier en /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 des manuels ne dit ce qui se passe si les deux mécanismes ne sont pas pris en charge, il s'interrompt probablement avec une erreur). Le nom du fichier est alors passé en argument sur la ligne de commande.
zsh
prend également en charge =(list)
comme remplacement possible pour <(list)
. Avec =(list)
un fichier temporaire est utilisé à la place du fichier dans /dev/fd
ou un FIFO. Il peut être utilisé en remplacement de <(list)
si le programme a besoin de lseek dans la sortie.
Selon le manuel ZSH, il pourrait également y avoir d'autres problèmes avec la façon dont <(list)
fonctionne :
Le
=
form est utile à la fois comme/dev/fd
et l'implémentation du canal nommé de<(...)
ont 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 tube (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 tube, de sorte que les programmes qui s'attendent à rechercher (voir la page de manuellseek(2)
) sur le fichier ne fonctionnera pas.
Notez qu'il s'agit d'une réponse bash, pas zsh.
Il y a des cas dans bash où vous ne pouvez pas utiliser de pipes :
some_command | some_other_command
parce que les tuyaux introduisent des sous-shells pour chaque composant du pipeline, lorsque les sous-shells sortent, tous les effets secondaires sur lesquels vous comptiez disparaîtraient. Par exemple, cet exemple artificiel :
cat file | while read line; do ((count++)); done
echo $count
affichera une ligne vide, car le $count
la variable 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 à partir d'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 du <()
traiter la syntaxe de substitution.