Sida 1 av 1
Asynkrona rörledningar [LÖST]
Postat: 14 jan 2009, 21:38
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
Re: Asynkrona rörledningar
Postat: 15 jan 2009, 17:57
av Konservburk
Har du försökt med pactl istället för pacmd?
Re: Asynkrona rörledningar
Postat: 15 jan 2009, 19:48
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.
Re: Asynkrona rörledningar
Postat: 15 jan 2009, 21:32
av Lars
Jag skulle vilja hävda att pacmd är felkonstruerat, men det hjälper ju inte dig

Re: Asynkrona rörledningar
Postat: 15 jan 2009, 21:54
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
Jag kom på enklare alternativ allt eftersom jag skrev

Re: Asynkrona rörledningar
Postat: 15 jan 2009, 22:26
av diwic
Perfekt mcNisse, you made my day!
Re: Asynkrona rörledningar
Postat: 15 jan 2009, 22:29
av Konservburk
mcNisse skrev:Så här kanske?
...
Jag kom på enklare alternativ allt eftersom jag skrev

Att ha med ett
sleep på det sättet är inte speciellt vackert
Borde kunna undvikas genom att göra typ så här:
Men jag håller med Lars om att det inte riktigt står rätt till med
pacmd.
Re: Asynkrona rörledningar
Postat: 15 jan 2009, 22:37
av diwic
Konservburk skrev:mcNisse skrev:Så här kanske?
...
Jag kom på enklare alternativ allt eftersom jag skrev

Att ha med ett
sleep på det sättet är inte speciellt vackert
Borde kunna undvikas genom att göra typ så här:
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 :-)
Re: Asynkrona rörledningar
Postat: 15 jan 2009, 23:27
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...
eller
... 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?
Re: Asynkrona rörledningar
Postat: 16 jan 2009, 09:04
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...
eller
... 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
(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"...?
Re: Asynkrona rörledningar
Postat: 16 jan 2009, 15:17
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
(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...
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

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
Re: Asynkrona rörledningar
Postat: 17 jan 2009, 13:32
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?
Re: Asynkrona rörledningar
Postat: 17 jan 2009, 14:31
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.