Newsgroup: it.comp.os.linux.iniziare
Titolo: Ci ho le redirezioni rotte :(

 
----   Xpost su .sys e .iniziare, f/up su .iniziare   ----
 
Avrei bisogno del vostro aiuto per comprendere perché alcune
redirezioni in bash (4.2.10) a volte mi funzionino correttamente,
ma altre volte no.
 
Diciamo che voglio lo stderr di un comando sul file err, e sia lo
stderr sia lo stdout sul file outanderr.
 
Si può fare in una vagonata di modi. Il problema è che moltissimi
di questi modi producono - spesso, ma non sempre - un file
outanderr incasinato, con output ed errore che si accavallano e/o
sono incompleti.
 
Per esempio:
 
lem@biggy:/tmp$ touch imafile
lem@biggy:/tmp$ (ls imafile idontexist 2>&1 >&3 | tee err >&3) 3>outanderr
lem@biggy:/tmp$ cat outanderr
ls: impossibile accedere a idontexist: File o directory non esistente
imafile
 
Sembra funzionare. Ma ridiamo il comando un po' di volte. Ecco quel che
succede:
 
lem@biggy:/tmp$ (ls imafile idontexist 2>&1 >&3 | tee err >&3) 3>outanderr
lem@biggy:/tmp$ cat outanderr
ls: impossibile accedere a idontexistimafile
: File o directory non esistente
 
Ora l'output (imafile) è finito nel bel mezzo dell'errore.
BTW: questa sopra l'ho provata anche in ksh, e il casino è lo stesso.
Quindi il problema non è né la mia versione di bash, né bash in sé
stessa.
 
Altra soluzione possibile:
 
lem@biggy:/tmp$ ((ls imafile idontexist >&3) 2> >(tee err >&4)) 3>outanderr 4>&3
lem@biggy:/tmp$ cat outanderr
ls: impossibile accedere a idontexist: File o directory non esistente
imafile
 
OK. Ora riproviamo, e dopo un po':
 
lem@biggy:/tmp$ ((ls imafile idontexist >&3) 2> >(tee err >&4)) 3>outanderr 4>&3
lem@biggy:/tmp$ cat outanderr
ls: impossibile accedere a idontexistimafile
 directory non esistente
 
Output in mezzo ad errore incompleto.
 
Pure queste soluzioni, qui sotto, danno problemi:
 
$ ls imafile idontexist >outanderr 2> >(tee err >>outanderr)
$ ls imafile idontexist >>outanderr 2> >(tee err >>outanderr)
 
L'unica cosa che pare generare sempre un outanderr corretto, tra
quelle che ho provato, è:
 
$ ls imafile idontexist 2> >(tee err >outanderr) | tee -a outanderr >/dev/null
 
Le quattro domande che mi pongo sono:
 
A) che cavolo succede?
 
B) dato che le redirezioni vengono tutte sistemate prima di eseguire
i comandi, che differenze ci sono tra le soluzioni malfunzionanti di
cui sopra e una cosa banalissima tipo:
$ ls imafile idontexist >outanderr 2>&1
che ovviamente funziona *sempre*?
Capisco che qui il comando è *uno* solo, ls, e che ls scrive
*sequenzialmente* output ed errori, e che quindi non si rischia la
contemporaneità teoricamente possibile colla compresenza di più comandi
che scrivono sullo stesso file, però:
 
C) perché allora una soluzione fra quelle sopra, l'ultima, pare sicura
e sempre funzionante? Lo è davvero, oppure è un caso? Se è sicura,
perché lo è? Come posso esser certo che un miscuglio di redirezioni
sarà sicuro?
 
D) perché in genere la *prima* volta che eseguo il comando, dopo aver
aperto un terminale, le cose funzionano? E invece *poi* non funzionano
più, spesso già dalla seconda volta (ma a volte bisogna aspettare di
più)?
 
Grazie per ogni vostro commento.
-- 
Bye, Lem
Ceterum censeo ISLAM esse delendum
_________________________________________________________________
Non sprecare i cicli idle della tua CPU, né quelli della tua GPU.
 
http://www.worldcommunitygrid.org/index.jsp
 
http://www.rnaworld.de/rnaworld/
 
http://home.edges-grid.eu/home/
 
 
http://www.gpugrid.net/
 

 più)?
 
Perché è la più semplice e pulita? Capricci dello scheduler?

 Fammi pensare...
 
Mi vien da pensare che quindi... l'unica mossa vincente sia non giocare?
Ossia: vanno bene tutte le redirezioni del mondo, purché due redirezioni
diverse non finiscano mai sullo stesso file - a meno che queste due
redirezioni non provengano dal medesimo comando (sola condizione che ci
assicuri la sequenzialità delle scritture, temo).
Altrimenti si rischia.
 
Insomma, tornando al mio esempio, l'unica roba davvero sicura sarebbe:
 
$ ls imafile idontexist >outanderr 2>err; cat err >>outanderr
 
e basta lì.


 $ ls imafile idontexist >outanderr 2>err; cat err >>outanderr
 
No. ma lasciami un po' di tempo. 
 
PS tempo fa ci fu una discussione su un  argomento simile.