Zoeken…


Opmerkingen

Procesvervanging is een vorm van omleiding waarbij de invoer of uitvoer van een proces (een reeks opdrachten) wordt weergegeven als een tijdelijk bestand.

Vergelijk twee bestanden van internet

Het volgende vergelijkt twee bestanden met diff met behulp van procesvervanging in plaats van tijdelijke bestanden te maken.

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

Voer een while-lus in met de uitvoer van een opdracht

Dit voedt een while lus met de uitvoer van een grep opdracht:

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

Met plakopdracht

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

Bestanden samenvoegen

Het is bekend dat u niet hetzelfde bestand kunt gebruiken voor invoer en uitvoer in dezelfde opdracht. Bijvoorbeeld,

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

doet niet wat je wilt. Tegen de tijd dat cat body.txt leest, is het al afgekapt door de omleiding en is het leeg. Het uiteindelijke resultaat is dat body.txt alleen de inhoud van header.txt .

Je zou kunnen denken om dit te vermijden met procesvervanging, dat wil zeggen dat het commando

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

zal de originele inhoud van body.txt op een of andere manier ergens in een buffer opslaan voordat het bestand wordt afgekapt door de omleiding. Het werkt niet. De cat tussen haakjes begint het bestand pas te lezen nadat alle bestandsdescriptors zijn ingesteld, net als de buitenste. In dit geval heeft het geen zin om te proberen procesvervanging te gebruiken.

De enige manier om een bestand voor te bereiden op een ander bestand is om een tussenliggend bestand te maken:

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

dat is wat sed of perl of vergelijkbare programma's onder het tapijt doen wanneer ze worden aangeroepen met een optie voor bewerken op de plaats (meestal -i ).

Stream een bestand door meerdere programma's tegelijk

Dit telt het aantal regels in een groot bestand met wc -l terwijl het tegelijkertijd wordt gecomprimeerd met gzip . Beide lopen tegelijkertijd.

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

Normaal schrijft tee zijn invoer naar een of meer bestanden (en stdout). We kunnen schrijven naar opdrachten in plaats van bestanden met tee >(command) .

Hier telt het commando wc -l >&2 de regels die worden gelezen van tee (die op zijn beurt van bigfile ). (Het aantal regels wordt verzonden naar stderr ( >&2 ) om te voorkomen dat er wordt gemengd met de invoer naar gzip .) De stdout van tee wordt tegelijkertijd in gzip ingevoerd.

Om het gebruik van een sub-shell te voorkomen

Een belangrijk aspect van procesvervanging is dat we hiermee het gebruik van een sub-shell kunnen vermijden bij het piping-commando's van de shell.

Dit kan worden aangetoond met een eenvoudig voorbeeld hieronder. Ik heb de volgende bestanden in mijn huidige map:

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

Als ik naar een while / read lus pijp, wordt de teller als volgt opgehoogd:

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

$count nu doet bevatten 6 , omdat het in de sub-shell context is aangepast. Alle onderstaande opdrachten worden uitgevoerd in een context van een subshell en het bereik van de gebruikte variabelen gaat verloren nadat de subshell wordt beëindigd.

command &
command | command 
( command )

Procesvervanging lost het probleem op door het gebruik van de van pipe | vermijden operator als in

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

Hierdoor blijft de waarde van de count behouden omdat er geen sub-shells worden aangeroepen.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow