Sök…


Anmärkningar

Processersättning är en form av omdirigering där inmatningen eller utdata från en process (viss sekvens med kommandon) visas som en tillfällig fil.

Jämför två filer från webben

Följande jämför två filer med diff hjälp av processersättning istället för att skapa tillfälliga filer.

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

Mata en stundslinga med utgången från ett kommando

Detta matar en while slinga med utgången av en grep kommando:

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

Med klistra in kommando

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

Sammanfoga filer

Det är välkänt att du inte kan använda samma fil för att mata in och mata ut i samma kommando. Till exempel,

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

gör inte vad du vill. När cat läser body.txt har den redan trunkerats av omdirigeringen och den är tom. Det slutliga resultatet blir att body.txt innehåller innehållet i header.txt .

Man kan tänka sig undvika detta med processersättning, det vill säga att kommandot

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

kommer att tvinga det ursprungliga innehållet i body.txt att på något sätt sparas i någon buffert någonstans innan filen trunkeras av omdirigeringen. Det fungerar inte. cat inom parentes börjar läsa filen först efter att alla filbeskrivningar har ställts in, precis som den yttre. Det är ingen mening att försöka använda processersättning i detta fall.

Det enda sättet att förbereda en fil till en annan fil är att skapa en mellanliggande:

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

vilket är vad sed eller perl eller liknande program gör under mattan när de kallas med ett edit-in-place- alternativ (vanligtvis -i ).

Strömma en fil genom flera program på en gång

Detta räknar antalet rader i en stor fil med wc -l samtidigt som det komprimeras med gzip . Båda körs samtidigt.

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

Normalt skriver tee sin inmatning till en eller flera filer (och stdout). Vi kan skriva till kommandon istället för filer med tee >(command) .

Här räknar kommandot wc -l >&2 raderna som läses från tee (som i sin tur läser från bigfile ). (Linjeräkningen skickas till stderr ( >&2 ) för att undvika blandning med ingången till gzip .) Stdout för tee matas samtidigt in i gzip .

För att undvika användning av ett underskal

En viktig aspekt av processersättning är att det låter oss undvika användning av ett sub-shell när vi rör kommandon från skalet.

Detta kan demonstreras med ett enkelt exempel nedan. Jag har följande filer i min nuvarande mapp:

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

Om jag rör till en while / read slingan som ökar en räknare enligt följande:

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

$count innehåller nu inte 6 , eftersom det modifierades i sub-shell-sammanhanget. Några av kommandona som visas nedan körs i ett sub-shell-sammanhang och räckvidden för de variabler som används inom går förlorade efter att sub-skalet upphör.

command &
command | command 
( command )

Processersättning kommer att lösa problemet genom att undvika att använda röret | operatör som i

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

Detta behåller count eftersom inga underskal anropas.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow