Asynkrona rörledningar [LÖST]

Här diskuterar vi skal, kommandon och klassiska linuxverktyg.
diwic
Inlägg: 96
Blev medlem: 27 jan 2008, 12:54
OS: Ubuntu
Utgåva: 20.04 Focal Fossa LTS
Kontakt:

Asynkrona rörledningar [LÖST]

Inlägg av diwic »

Hoppas inte ämnesraden lät för avskräckande ;-)

Jag försöker få ut information från ett program, pacmd, men programmet är lite dumt. Hade det varit ett "vanligt" program hade man enkelt kunna skriva typ "pacmd < fil1 > fil2", men det funkar inte eftersom programmet ger svaren asynkront, och pacmd avslutas så fort fil1 är slut. Så pacmd avslutar sig innan den hunnit få svar på kommandona.
Vad jag skulle behöva är att istället för att den bara läser fil1, så behöver jag något som skickar innehållet i fil1 (eller en hårdkodad sträng), väntar ett par sekunder eller så, och sedan skickar EOF.

Detta går säkert att göra i C/Python/etc, men går det att göra i ett Bash-skript?

// David
Senast redigerad av 1 diwic, redigerad totalt 15 gånger.
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Asynkrona rörledningar

Inlägg av Konservburk »

Har du försökt med pactl istället för pacmd?
diwic
Inlägg: 96
Blev medlem: 27 jan 2008, 12:54
OS: Ubuntu
Utgåva: 20.04 Focal Fossa LTS
Kontakt:

Re: Asynkrona rörledningar

Inlägg av diwic »

Konservburk skrev:Har du försökt med pactl istället för pacmd?
Nja, kommandona jag letar efter finns tyvärr inte i pactl.
Lars
Inlägg: 6191
Blev medlem: 14 jan 2007, 19:31
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Ort: Stockholm

Re: Asynkrona rörledningar

Inlägg av Lars »

Jag skulle vilja hävda att pacmd är felkonstruerat, men det hjälper ju inte dig :P
Användarvisningsbild
mcNisse
Inlägg: 5211
Blev medlem: 06 feb 2007, 20:51
OS: Debian
Utgåva: Vet inte/ingen utgåva passar

Re: Asynkrona rörledningar

Inlägg av mcNisse »

Så här kanske?

Kod: Markera allt

(echo rad1
echo rad2
....
sleep 10) | pacmd > fil2
eller

Kod: Markera allt

(while read line; do echo $line;done < fil1; sleep 10) | pacmd > fil2
eller

Kod: Markera allt

(cat fil1;sleep 10) | pacmd > fil2
Jag kom på enklare alternativ allt eftersom jag skrev :P
diwic
Inlägg: 96
Blev medlem: 27 jan 2008, 12:54
OS: Ubuntu
Utgåva: 20.04 Focal Fossa LTS
Kontakt:

Re: Asynkrona rörledningar

Inlägg av diwic »

mcNisse skrev:

Kod: Markera allt

(cat fil1;sleep 10) | pacmd > fil2
Perfekt mcNisse, you made my day!
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Asynkrona rörledningar

Inlägg av Konservburk »

mcNisse skrev:Så här kanske?
...

Kod: Markera allt

(cat fil1;sleep 10) | pacmd > fil2
Jag kom på enklare alternativ allt eftersom jag skrev :P
Att ha med ett sleep på det sättet är inte speciellt vackert :P

Borde kunna undvikas genom att göra typ så här:

Kod: Markera allt

(: | cat fil1 &) | pacmd > fil2
Men jag håller med Lars om att det inte riktigt står rätt till med pacmd.
diwic
Inlägg: 96
Blev medlem: 27 jan 2008, 12:54
OS: Ubuntu
Utgåva: 20.04 Focal Fossa LTS
Kontakt:

Re: Asynkrona rörledningar

Inlägg av diwic »

Konservburk skrev:
mcNisse skrev:Så här kanske?
...

Kod: Markera allt

(cat fil1;sleep 10) | pacmd > fil2
Jag kom på enklare alternativ allt eftersom jag skrev :P
Att ha med ett sleep på det sättet är inte speciellt vackert :P

Borde kunna undvikas genom att göra typ så här:

Kod: Markera allt

(: | cat fil1 &) | pacmd > fil2
Men jag håller med Lars om att det inte riktigt står rätt till med pacmd.
Det var många intressanta tecken där, du får gärna förklara hur/varför det funkar utan en sleep :-)
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Asynkrona rörledningar

Inlägg av Konservburk »

diwic skrev:Det var många intressanta tecken där, du får gärna förklara hur/varför det funkar utan en sleep :-)
När du ber mig förklara vad som händer så inser jag att det egentligen räker med detta...

Kod: Markera allt

(: | cat fil1) | pacmd > fil2
eller

Kod: Markera allt

{ : | cat fil1 ; } | pacmd > fil2
... om man nu tycker att det är onödigt att dra igång ett subskal bara för att gruppera rören.

Syftet är att få cat fil1 att utvärderas innan pacmd. Det viktiga är med andra ord att tvinga fram så att rören "kopplas" i rätt ording, därav (krull)parenteserna. Själva kolonet är ett kommando som inte gör något, men som i det här fallet behövs för att få till en rörledning.

Är det en tillräckligt bra förklaring?
diwic
Inlägg: 96
Blev medlem: 27 jan 2008, 12:54
OS: Ubuntu
Utgåva: 20.04 Focal Fossa LTS
Kontakt:

Re: Asynkrona rörledningar

Inlägg av diwic »

Konservburk skrev:
diwic skrev:Det var många intressanta tecken där, du får gärna förklara hur/varför det funkar utan en sleep :-)
När du ber mig förklara vad som händer så inser jag att det egentligen räker med detta...

Kod: Markera allt

(: | cat fil1) | pacmd > fil2
eller

Kod: Markera allt

{ : | cat fil1 ; } | pacmd > fil2
... om man nu tycker att det är onödigt att dra igång ett subskal bara för att gruppera rören.

Syftet är att få cat fil1 att utvärderas innan pacmd. Det viktiga är med andra ord att tvinga fram så att rören "kopplas" i rätt ording, därav (krull)parenteserna. Själva kolonet är ett kommando som inte gör något, men som i det här fallet behövs för att få till en rörledning.

Är det en tillräckligt bra förklaring?
Nja, det viktiga är väl att pacmd hinner få svar innan man stänger ner in-pipen? Jag har testat dina tre alternativ, eller rättare sagt, jag har ändrat till

Kod: Markera allt

( : | echo "info" ) | pacmd > fil2 
(men jag antar att det inte borde göra någon skillnad), och utan redirect till fil2, så funkar det bara ibland - ibland får jag bara hälften av svaret på "info" tillbaka. Med redirect till fil2 så har det funkat hittills, men frågan är om det bara är en slump, och samma fel kan uppstå ändå (fast mindre frekvent), eller om redirect till fil2 spelar en viktig roll i kedjan här?

Vidare undrar jag vad det är för skillnad på att bara göra "cat fil1" mot att göra ingenting, och sedan skicka resultatet av ingenting till "cat fil1"...?
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Asynkrona rörledningar

Inlägg av Konservburk »

diwic skrev:Nja, det viktiga är väl att pacmd hinner få svar innan man stänger ner in-pipen?
Såklart ;)
diwic skrev:Jag har testat dina tre alternativ, eller rättare sagt, jag har ändrat till

Kod: Markera allt

( : | echo "info" ) | pacmd > fil2 
(men jag antar att det inte borde göra någon skillnad), och utan redirect till fil2, så funkar det bara ibland - ibland får jag bara hälften av svaret på "info" tillbaka. Med redirect till fil2 så har det funkat hittills, men frågan är om det bara är en slump, och samma fel kan uppstå ändå (fast mindre frekvent), eller om redirect till fil2 spelar en viktig roll i kedjan här?
Det ska inte spela någon roll om du skickar utdatan till fil2 eller stdout. Funkar det bara "ibland" i ena fallet så är det samma sak även i andra. Det skulle möjligtvis kunna hjälpa att ta till samma trick en gång till med en rörledning även på andra sidan...

Kod: Markera allt

(: | echo info) | pacmd | cat > fil2 
diwic skrev:Vidare undrar jag vad det är för skillnad på att bara göra "cat fil1" mot att göra ingenting, och sedan skicka resultatet av ingenting till "cat fil1"...?
Det är själva rörledningen vi vill åt... Spelar ingen roll vad den gör så länge det blir samma utdata :P Du skulle t.ex. kunna använda cat fil1 | cat istället för : | cat fil1 om du tycker det blir finare.

Men om det här nu bara funkar "ibland" så är det såklart bättre att ordna något som är mer robust, förslagsvis med filrör...

Kod: Markera allt

(cat fil1; <fifo) | pacmd > fil2 &

# gör vad du nu vill göra med fil2
#

# stäng filröret
>fifo 
Elle kanske ännu bättre...
skicka kommandon till pacmd över ett filrör och ta emot resultatet över ett annat:

Kod: Markera allt

while grep . fifo1; do :; done | pacmd >fifo2 &

# skicka ett kommando till pacmd
echo info >fifo1

# läs av resultatet och gör vad du nu vill göra med det

# skicka fler kommandon till pacmd
# osv

# stäng filröret
>fifo1
diwic
Inlägg: 96
Blev medlem: 27 jan 2008, 12:54
OS: Ubuntu
Utgåva: 20.04 Focal Fossa LTS
Kontakt:

Re: Asynkrona rörledningar

Inlägg av diwic »

Konservburk skrev: Men om det här nu bara funkar "ibland" så är det såklart bättre att ordna något som är mer robust, förslagsvis med filrör...

Kod: Markera allt

(cat fil1; <fifo) | pacmd > fil2 &

# gör vad du nu vill göra med fil2
#

# stäng filröret
>fifo 
Tack för all hjälp, men...

Jag kommer väl ändå inte ifrån att det behövs en sleep innan man nu gör vad man vill med fil2? Eftersom & har forkat nåt separat vet jag ju inte när det är klart, eller?

Första gången jag ser fifos i bash, jag har försökt leta efter information om detta men inte hittat. Är fifo/fifo1/fifo2 ord med specialbetydelser i bash/linux? Måste man inte skapa fifos med mkfifo?
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Asynkrona rörledningar

Inlägg av Konservburk »

diwic skrev:Jag kommer väl ändå inte ifrån att det behövs en sleep innan man nu gör vad man vill med fil2? Eftersom & har forkat nåt separat vet jag ju inte när det är klart, eller?
Just eftersom du "inte vet" när det är klart så är det dumt att använda sleep. Förmodligen sover du på tok för länge, men det finns inga som helst garantier att du inte sover för kort tid.

Tanken är att när du gör vad du nu vill göra med fil2 även testar så att du verkligen får fram det du är intresserad av. När du är klar och vet att du har fått reda på det du vill så stänger du filröret.
diwic skrev:Första gången jag ser fifos i bash, jag har försökt leta efter information om detta men inte hittat. Är fifo/fifo1/fifo2 ord med specialbetydelser i bash/linux?
Nej, det där är bara vad jag namngav dem till. Jag hade kunna använda i princip vilka namn som helst.
diwic skrev:Måste man inte skapa fifos med mkfifo?
Nja... Du måste skapa dina fifos, men just mkfifo är inte det enda sättet.
Skriv svar

Återgå till "Terminalforum"