Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Vlákno názorů k článku
Hrátky z řádky: pomocné soubory a zamykání

uživatel si přál zůstat v anonymitě
7. 4. 2008 10:27

Proc tohle nefunguje?

Mel jsem ted v gentoo problem s odinstalaci texinfo. Mel v prerm zvlastni konstrukci, ktera nefungovala ani, kdyz jsem udelal testovaci soubor. Jde mi o tohle:
#!/bin/bash

function tisk() {
  echo -e "line 1\nline 2\nline 3\nline 4"
}

while read nacteno;do echo "precetl $nacteno";done <(tisk)
Po spusteni to zahlasi chybu
./a: line 7: syntax error near unexpected token `<(tisk)'
./a: line 7: `while read nacteno;do echo "precetl $nacteno";done <(tisk)'
Pritom ale nasledujici kod probehne v poradku
#!/bin/bash

function tisk() {
  echo -e "line 1\nline 2\nline 3\nline 4"
}

cat <(tisk)
Mate nekdo tuseni, proc nefunguje presmerovani stdin do toho read?
Pichi aura:75
7. 4. 2008 10:50

Re: Proc tohle nefunguje?

Konstrukce <() funguje v bashi spíše jako makro. spustí podproces a jeho výstup přesměruje do roury a tu rouru předá jako parametr. klíčové slovo done pochopitelně nečeká žádný parametr
$ echo <(echo "ahoj")
/dev/fd/63 
Místo
while read nacteno;do echo "precetl $nacteno";done <(tisk) 
prostě použij
tisk | while read nacteno;do echo "precetl $nacteno";done 
a je vymalováno.
uživatel si přál zůstat v anonymitě
7. 4. 2008 11:02

Re: Proc tohle nefunguje?

dik za odpoved. Ja osobne pouzivam konstrukce ( prikaz1 ; prikaz2 ; prikaz3 ) | while read .... denne, vcetne zjednodusene formy prikaz | while ..... Tohle byl problem v jinem skriptu, ale privedlo me to na jednu myslenku. Pokud spustim prikaz | while read ... ; do A=neco;done, pak promenna A je zapomenuta a v dalsim kodu ji nepouziju. Tak jsem myslel, ze ten <() by mohl tenhle problem resit. while by se provadelo v aktualnim bashi akorat vstup by byl zmenenej z toho prikazu. Jina moznost me napadla zduplikovat STDIN a pak na stdin presmerovat vystup z toho programu neco jako exec 15<&0 <(tisk), ale tohle se mi taky nejak nepovedlo, stejne tak ani bash -c 'while read .....' <(tisk), coz by ale snad fungovat melo.

Nejakej napad, jak spustit while na vystup z nejakyho programu tak, aby ten while bezel v aktualnim bashi a nespustil podproces a zachovaly se tak nastaveni promennych v aktualnim bashi?

Pichi aura:75
7. 4. 2008 11:34

Re: Proc tohle nefunguje?

Na to existuje jediné řešení: Použij sílu (nějaký skutečný programovací jazyk) Luku.
uživatel si přál zůstat v anonymitě
7. 4. 2008 11:39

Re: Proc tohle nefunguje?

No, to je odpoved teda docela dost mimo misu:-) Osobne to spis resim tak, ze z toho prikaz | while ... udelat pomoci echo vystup ve tvaru PROM=VAL a pak davam eval. Ale je to takovy neohrabany, stejne, jako by bylo neohrabany psat 5 radkovy bash skript v nejakym vyssim jazyce.
Pichi aura:75
7. 4. 2008 15:15

Re: Proc tohle nefunguje?

Když už se pustíš do
... udelat pomoci echo vystup ve tvaru PROM=VAL a pak davam eval ...
tak to už není pětiřádkový bash skript. No a když to nahradím tří řádkovým perl skriptem takový deseti řádkový bash a bez evalů, tak už se to vyplatí.
Ash
Ash (neregistrovaný)
7. 4. 2008 23:49

Re: Proc tohle nefunguje?

> Tak jsem myslel, ze ten <() by mohl tenhle problem resit.

Ano, konstrukce <() se v bashi skutečně za tím to účelem (zachování proměnných) používá.
9x0
9x0 (neregistrovaný)
7. 4. 2008 21:50

Re: Proc tohle nefunguje?

Pokial som to spravne pochopil, tak process substitution ti nahradi <(tisk) v kode za subor, kde sa nachadza vystup funkcie tisk. Budes tam mat teda nieco ako:

while read nacteno;do echo "precetl $nacteno";done /subor

Ty ale chces medzi done a <(tisk) vlozit <, aby si dostal

while read nacteno;do echo "precetl $nacteno";done < /subor

Vid http://tldp.org/LDP/abs/html/process-sub.html - maju tam priklad podobny tvojmu
Pichi aura:75
8. 4. 2008 9:23

Re: Proc tohle nefunguje?

Nojo, funguje to:
$ function tisk() {
>   echo -e "line 1\nline 2\nline 3\nline 4"
> }
$
$ while read nacteno;do echo "precetl $nacteno";done < <(tisk)
precetl line 1
precetl line 2
precetl line 3
precetl line 4
$
Zasílat nově přidané příspěvky e-mailem