Recherche…


Remarques

La substitution de processus est une forme de redirection dans laquelle l'entrée ou la sortie d'un processus (une séquence de commandes) apparaît sous la forme d'un fichier temporaire.

Comparer deux fichiers du Web

Ce qui suit compare deux fichiers avec diff utilisant la substitution de processus au lieu de créer des fichiers temporaires.

diff <(curl http://www.example.com/page1) <(curl http://www.example.com/page2)

Alimenter une boucle while avec la sortie d'une commande

Cela alimente un while en boucle avec la sortie d'un grep commande:

while IFS=":" read -r user _
do
    # "$user" holds the username in /etc/passwd
done < <(grep "hello" /etc/passwd)

Avec la commande coller

# Process substitution with paste command is common
# To compare the contents of two directories
paste <( ls /path/to/directory1 ) <( ls /path/to/directory1 )

Fichiers concaténés

Il est bien connu que vous ne pouvez pas utiliser le même fichier pour l'entrée et la sortie dans la même commande. Par exemple,

$ cat header.txt body.txt >body.txt

ne fait pas ce que vous voulez Au moment où cat lit body.txt , il a déjà été tronqué par la redirection et il est vide. Le résultat final sera que body.txt contiendra body.txt le contenu de header.txt .

On pourrait penser à éviter cela avec la substitution de processus, c’est-à-dire que la commande

$ cat header.txt <(cat body.txt) > body.txt

forcera le contenu original de body.txt à être sauvegardé dans un tampon quelque part avant que le fichier ne soit tronqué par la redirection. Ça ne marche pas Le cat entre parenthèses commence à lire le fichier uniquement après que tous les descripteurs de fichiers ont été configurés, tout comme celui externe. Il est inutile d'essayer d'utiliser la substitution de processus dans ce cas.

La seule façon d'ajouter un fichier à un autre fichier consiste à créer un fichier intermédiaire:

$ cat header.txt body.txt >body.txt.new
$ mv body.txt.new body.txt

c'est ce que font les programmes sed ou perl ou similaires sous le tapis lorsqu'ils sont appelés avec une option edit-in-place (généralement -i ).

Diffuser un fichier via plusieurs programmes à la fois

Cela compte le nombre de lignes dans un gros fichier avec wc -l tout en le compressant simultanément avec gzip . Les deux fonctionnent en même temps.

tee >(wc -l >&2) < bigfile | gzip > bigfile.gz

Normalement, tee écrit son entrée dans un ou plusieurs fichiers (et stdout). Nous pouvons écrire dans les commandes au lieu des fichiers avec tee >(command) .

Ici, la commande wc -l >&2 compte les lignes lues depuis le tee (qui à son tour lit depuis le bigfile ). (Le nombre de lignes est envoyé à stderr ( >&2 ) pour éviter de mélanger avec l'entrée de gzip .) La sortie standard de tee est transmise simultanément à gzip .

Pour éviter l'utilisation d'un sous-shell

Un aspect majeur de la substitution de processus est qu’il nous permet d’éviter l’utilisation d’un sous-shell lorsqu’il commande des commandes depuis le shell.

Cela peut être démontré par un exemple simple ci-dessous. J'ai les fichiers suivants dans mon dossier actuel:

$ find . -maxdepth 1 -type f -print
foo bar zoo foobar foozoo barzoo 

Si je conduis vers une boucle while / read qui incrémente un compteur comme suit:

count=0
find . -maxdepth 1 -type f -print | while IFS= read -r _; do
    ((count++))
done

$count maintenant ne contient pas 6 , car il a été modifié dans le contexte du sous-shell. Toutes les commandes présentées ci-dessous sont exécutées dans un contexte de sous-shell et la portée des variables utilisées est perdue après la fin du sous-shell.

command &
command | command 
( command )

La substitution de processus résoudra le problème en évitant d'utiliser le tuyau | opérateur comme dans

count=0
while IFS= read -r _; do
    ((count++))
done < <(find . -maxdepth 1 -type f -print)

Cela conservera la valeur de la variable count car aucun sous-shell n'est invoqué.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow