Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: kapetr 21 Února 2014, 15:11:30
-
Může mi někdo poradit v čem je problém ? (Nebo se picnu :-)
$ tzap -r -c /etc/channels.conf "CT 1" 2>&1
using '/dev/dvb/adapter0/frontend0' and '/dev/dvb/adapter0/demux0'
reading channels from file '/etc/channels.conf'
tuning to 730000000 Hz
video pid 0x0101, audio pid 0x0111
status 00 | signal ffff | snr 0122 | ber 00000000 | unc 00000190 |
status 1f | signal ffff | snr 0000 | ber 00000000 | unc 00000190 | FE_HAS_LOCK
status 1f | signal ffff | snr 0118 | ber 00000000 | unc 00000190 | FE_HAS_LOCK
status 1f | signal ffff | snr 0122 | ber 00000000 | unc 00000190 | FE_HAS_LOCK
^C
OK - pozn.: řádky, co mě zajímají posílá tzap do stderr.
$ tzap -r -c /etc/channels.conf "CT 1" 2>&1 |grep status
status 00 | signal ffff | snr 0118 | ber 00000000 | unc 00000190 |
status 1f | signal ffff | snr 0000 | ber 00000000 | unc 00000190 | FE_HAS_LOCK
status 1f | signal ffff | snr 0118 | ber 00000000 | unc 00000190 | FE_HAS_LOCK
status 1f | signal ffff | snr 0122 | ber 00000000 | unc 00000190 | FE_HAS_LOCK
^C
OK - grep dostane na vstup i to z stderr of tzap, výsledek pošle na svůj stdout
$ tzap -r -c /etc/channels.conf "CT 1" 2>&1 |cut -c 2-5
sing
unin
ideo
tatu
tatu
tatu
^C
OK - i cut má na vstupu co čekám.
$ tzap -r -c /etc/channels.conf "CT 1" 2>&1 |grep status|cut -c 2-5
^C
Nevyleze NIC !?!?
Jak to, že cut nedostane na vstup výstup z grep ?!
Díky.
-
$ tzap -r -c /etc/channels.conf "CT 1" 2>&1 | cut -c 2-5 | grep tatu
-
Také nic.
To je síla, co ?
Místo tzap pro zkoušení lze použít např. toto:
while true; do echo ahoj; sleep 1; echo koko; sleep 1; done |grep koko|cut -c 2-4
Chová se to identicky.
-
Jsem zrovna na stroji s widlemi, takze jen po pameti... co je vlastne cilem tveho usili?
-
... momentálně především aby mi fungovala tak elementární věc, jako je řetězení příkazů.
To, jak jsem na to narazil, je oproti tomuhle krajně nezajímavé - zachytávat výstup programu posílajícího na výstup v pravidelných intervalech stavové řádky a jejich zpracování.
-
Ono to funguje, ale výsledek se vypíše až tehdy, když zdrojový proces skončí. Pokud by to mělo vypisovat hned, bude třeba oddělit zpracování toho streamu do nezávislého celku, zhruba takto:
tzap -r -c /etc/channels.conf "CT 1" 2>&1 | while read i; do echo $i | grep status | cut -c 2-5 ; done
while si běží ve vlastním subshellu a zpracovává každý řádek zvlášť.
-
A kde je zakopaný pes ? Tomu stále nerozumím.
Který proces čeká až na dokončení kterého ?
Jak grep tak cut předávají na výstup vstup průběžně. (Jsou to řádky zpracovávající programy, které mají v sobě sami takovou while read/do něco + echo/done smyčku.)
Jaký je rozdíl, zda na vstup např. cut-u přichází průběžný výstup tzap nebo průběžný výstup grep ?
-
Sice jsem před časem roury a přesměrování pitval hodně a dokonce to všechno sepsal, ale přiznám se, že tohle teď nezdůvodním. Takže buď jsem něco zapoměl, nebo úplně minul..
-
Tak to má na svědomí buffer, který je používán na výstupu. Jeho chování se dá upravit příkazem stdbuf, u grepu přímo přepínačem --line-buffered, tak, aby plival každý řádek.
tzap -r -c /etc/channels.conf "CT 1" 2>&1 | stdbuf -oL grep status | cut -c 2-5
tzap -r -c /etc/channels.conf "CT 1" 2>&1 | grep --line-buffered status | cut -c 2-5
http://stackoverflow.com/questions/13858912/piping-tail-output-though-grep-twice (http://stackoverflow.com/questions/13858912/piping-tail-output-though-grep-twice)
-
Moc děkuji - podrobněji to prostuduji.
Jenže to má jeden háček. Jak jsem již uvedl - pokud spustím:
tzap -r -c /etc/channels.conf "CT 1" 2>&1 |grep status
Tak grep to plive průběžně ven - nijak to ve svém výstupním bufferu nekumuluje.
Čili otázka zní - proč to na terminál vypadává průběžně (po řádcích) a když je tam roura, tak ne ?
Myslím, že by se to mělo chovat v obou případech stejně - že by grep zkoumal na co/kam je napojen jeho stdout descriptor si tak nějak nedovedu představit.
Popravdě - s fungováním bufferů/semaforů mám problémy i jinde.
Také často používám:
alias tl='tail -n 444 -f /var/log/syslog|grep -Ev "named\[|sflphoned: <info>"'
a ačkoli je tam jen 1 grep, tak když je příkaz déle spuštěn, tak nakonec přestane vypisovat, ačkoli tam jsou již další zprávy. Také nevím proč.
-
genericka rada" kdyz nevis bashi, tak `set -x' ;)
-
Je to triviální a dočteš se to na odkaze z mého odkazu ;) Pokud grep (a další programy) ví, že výstup jde do terminálu, buffer nepoužije, ale pokud běží v rouře, počítá s tím, že příjemcem není člověk a bufferuje, aby ušetřil systémové prostředky.
-
Tak tím je to vysvětleno - ještě jednou díky a zdravím.