Live Support My forum, my way! Il forum dei newsgroup: Linux » Bash - stdout e stderr su 2 variabili
My forum, my way! Il forum dei newsgroup
Fast Uncompromising Discussions.Newsgroup FUDforum will get your users talking.

Loading
Utenti      F.A.Q.    Registrati    Login    Home
Home » Computer » Linux » Bash - stdout e stderr su 2 variabili
Bash - stdout e stderr su 2 variabili [messaggio #40541] mar, 19 luglio 2011 21:41 Messaggio successivo
BIG (Umberto)  è attualmente disconnesso BIG (Umberto)
Messaggi: 9
Registrato: luglio 2011
Junior Member
Curiositá.
Stavo pastrocciando con zenity per avere una interfaccia grafica al comando
zbarimg (decodificatore di qr-code).
Mi serviva avere 2 finestre diverse, a seconda se il comando era eseguito su
una immagine valida oppure una finestra con l'errore di decodifica.
Per ora ho risolto leggendo lo stato di errore in uscita e richiamando una
seconda volta zbarimg reindirizzando stderr su stdout.

QR=$(zbarimg -q $filescelto)
e se $? da un valore diverso da zero:
error=$(zbarimg -v $filescelto 2>&1)

Pensavo di riuscire ad ottenere il tutto con un solo passaggio (utile anche per
eventuali altri casi).

Googlando non ne sono venuto a capo.


--
+----------------------------------------------------------- ----------------+
| Sappi che la mia spocchiosita' depressiva con pulsione |
| all'autodemolizione e' allo studio di menti brillanti del mondo della |
| psichiatria. Hanno promesso di spiegarmi che cosa ho detto. |
+-----#17--------------------Campagna contro le pubblicita` idiote.---------+
Re: Bash - stdout e stderr su 2 variabili [messaggio #40543 è una risposta a message #40541] mar, 19 luglio 2011 23:57 Messaggio precedenteMessaggio successivo
Alessandro Selli  è attualmente disconnesso Alessandro Selli
Messaggi: 242
Registrato: novembre 2010
Senior Member
BIG (Umberto) ha scritto:
> Curiositá.
> Stavo pastrocciando con zenity per avere una interfaccia grafica al comando
> zbarimg (decodificatore di qr-code).
> Mi serviva avere 2 finestre diverse, a seconda se il comando era eseguito su
> una immagine valida oppure una finestra con l'errore di decodifica.
> Per ora ho risolto leggendo lo stato di errore in uscita e richiamando una
> seconda volta zbarimg reindirizzando stderr su stdout.
>
> QR=$(zbarimg -q $filescelto)
> e se $? da un valore diverso da zero:

Fai attenzione che lo stderr non ha necessariamente a che fare con
l'exit status, che raccoglie anche i messaggi che non è previsto
indichino una condizione d'errore (i warning, ad es.).

> error=$(zbarimg -v $filescelto 2>&1)
>
> Pensavo di riuscire ad ottenere il tutto con un solo passaggio (utile anche per
> eventuali altri casi).

Il modo più semplice che mi viene in mente è usando una named pipe.
Lo faccio vedere con un esempio creato ad arte.

Creo le condizioni per avere un comando (ls) che mi crei un output
verso lo standard output e uno verso lo standard error:

$ touch pippo
$ ls pippo pluto
ls: impossibile accedere a pluto: File o directory non esistente
pippo

Creo la named pipe:

$ mkfifo stderr

Catturo lo standard output nella variabile STDIN e lo standard error
nella variabile STDERR con un'unica esecuzione di ls:

$ STDIN=$(ls pippo pluto 2> stderr) & STDERR=$(cat stderr)
[1] 3706
$
[1]+ Exit 2 STDIN=$(ls pippo pluto 2> stderr)
$ echo -e $STDERR\\n$STDIN
ls: impossibile accedere a pluto: File o directory non esistente
pippo

A fare le cose da manuale si dovrebbe fare un wait sul PID del comando
in background, ossia in questo esempio del comando STDIN=$(ls pippo
pluto 2> stderr), PID che è disponibile nella variabile della shell !.
Questo per essere sicuri che quando si va a leggere il contenuto della
variabile STDIN il comando che le deve fornire i dati abbia terminato
l'esecuzione. Ossia, prima dell'ultimo comando si dovrebbe fare un:

$ wait $!

Inutile in questo caso perché si è già visto il messaggio della shell
"[1]+ Exit 2 STDIN=$(ls pippo pluto 2> stderr)" che attesta la fine del
job. Messaggio che però compare sul terminale di una shell interattiva,
non è prodotto invece da una shell non interattiva (quella di uno script).

Nota che non ci si prende cura dell'exit status: si hanno le variabili
STDIN e STDERR popolate dai messaggi dello stdout e dello srderr a
prescindere che il comando sia incorso in errori oppure no.


Ciao,


--
Alessandro Selli http://alessandro.route-add.net
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.
Re: Bash - stdout e stderr su 2 variabili [messaggio #40552 è una risposta a message #40543] mer, 20 luglio 2011 13:37 Messaggio precedenteMessaggio successivo
BIG (Umberto)  è attualmente disconnesso BIG (Umberto)
Messaggi: 9
Registrato: luglio 2011
Junior Member
Alessandro Selli in data Tuesday 19 July 2011 23:57, nel gruppo
it.comp.os.linux.iniziare ha scritto:

> Creo la named pipe:
>
> $ mkfifo stderr
>
> Catturo lo standard output nella variabile STDIN e lo standard error
> nella variabile STDERR con un'unica esecuzione di ls:
>
> $ STDIN=$(ls pippo pluto 2> stderr) & STDERR=$(cat stderr)
> [1] 3706
> $
> [1]+ Exit 2 STDIN=$(ls pippo pluto 2> stderr)
> $ echo -e $STDERR\\n$STDIN
> ls: impossibile accedere a pluto: File o directory non esistente
> pippo

L'idea é buona, ma STDIN mi esce sempre con una stringa vuota.

> Nota che non ci si prende cura dell'exit status: si hanno le variabili
> STDIN e STDERR popolate dai messaggi dello stdout e dello srderr a
> prescindere che il comando sia incorso in errori oppure no.

Direi che nell'esempio, l'exit status viene influenzato dall'ultima parte del
comando (cat stderr) per cui é inutilizzabile.


--
+----------------------------------------------------------- ----------------+
| Il Pascal e' un linguaggio giocattolo fatto per insegnare la |
| programmazione ai matematici. |
+-----#20--------------------Campagna contro le pubblicita` idiote.---------+
Re: Bash - stdout e stderr su 2 variabili [messaggio #40561 è una risposta a message #40552] mer, 20 luglio 2011 20:16 Messaggio precedenteMessaggio successivo
Alessandro Selli  è attualmente disconnesso Alessandro Selli
Messaggi: 242
Registrato: novembre 2010
Senior Member
BIG (Umberto) ha scritto:
> Alessandro Selli in data Tuesday 19 July 2011 23:57, nel gruppo
> it.comp.os.linux.iniziare ha scritto:
>
>> Creo la named pipe:
>>
>> $ mkfifo stderr
>>
>> Catturo lo standard output nella variabile STDIN e lo standard error
>> nella variabile STDERR con un'unica esecuzione di ls:
>>
>> $ STDIN=$(ls pippo pluto 2> stderr) & STDERR=$(cat stderr)
>> [1] 3706
>> $
>> [1]+ Exit 2 STDIN=$(ls pippo pluto 2> stderr)
>> $ echo -e $STDERR\\n$STDIN
>> ls: impossibile accedere a pluto: File o directory non esistente
>> pippo
>
> L'idea é buona, ma STDIN mi esce sempre con una stringa vuota.

Eseguendo i comandi dell'esempio? No ho barato, ho copincollato da un
terminale in cui li ho eseguiti davvero. Nota che lo stdin non è mai
rediretto, e anzi è catturato nello stesso modo in cui tui lo facevi nel
tuo primo post:

> QR=$(zbarimg -q $filescelto)
> e se $? da un valore diverso da zero:
> error=$(zbarimg -v $filescelto 2>&1)

Se la variabile STDIN rimane vuota deve voler dire che non c'è stato
output verso lo standard out.

>> Nota che non ci si prende cura dell'exit status: si hanno le variabili
>> STDIN e STDERR popolate dai messaggi dello stdout e dello srderr a
>> prescindere che il comando sia incorso in errori oppure no.
>
> Direi che nell'esempio, l'exit status viene influenzato dall'ultima parte del
> comando (cat stderr) per cui é inutilizzabile.

Ti servisse l'exit status di ls (o di quale comando in realtà usi)
allora devi eseguire wait $!. Anche se non c'è più nulla da attendere
(il comando in background ha terminato l'esecuzione prima che sia
lanciato il comando wait), wait $! ti restituisce l'exit code
dell'ultimo comando eseguito in background.


Ciao,


--
Alessandro Selli http://alessandro.route-add.net
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.
Re: Bash - stdout e stderr su 2 variabili [messaggio #40562 è una risposta a message #40561] mer, 20 luglio 2011 20:37 Messaggio precedenteMessaggio successivo
BIG (Umberto)  è attualmente disconnesso BIG (Umberto)
Messaggi: 9
Registrato: luglio 2011
Junior Member
Alessandro Selli in data Wednesday 20 July 2011 20:16, nel gruppo
it.comp.os.linux.iniziare ha scritto:

> Se la variabile STDIN rimane vuota deve voler dire che non c'è stato
> output verso lo standard out.

per non sbagliare ho batto uno script!

#!/bin/bash
clear
mkfifo stderr
touch pippo
echo
STDIN=$(ls pippo pluto 2> stderr) & STDERR=$(cat stderr)
status=$?
plink=$!
wait $!
echo pid=$plink ---- status=$status
echo ===[$STDERR]
echo ===[$STDIN]
echo
rm stderr


Che lanciato in /tmp


pid=21170 ---- status=0
===[ls: impossibile accedere a pluto: No such file or directory]
===[]

Sostituendo
STDIN=$(ls pippo pluto 2> stderr) & STDERR=$(cat stderr)
con
STDIN=$(ls pippo pluto 1> stderr) & STDERR=$(cat stderr)

ottengo:
ls: impossibile accedere a pluto: No such file or directory
pid=21188 ---- status=0
===[pippo]
===[]


Potesse essere (sono su debian)?
big@debian:/tmp$ bash --version
GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.



--
+----------------------------------------------------------- ----------------+
| Da un errore di windows (visto realmente): |
| Keyboard not found! Press F1 to continue. |
+-----#28--------------------Campagna contro le pubblicita` idiote.---------+
Re: Bash - stdout e stderr su 2 variabili [messaggio #40564 è una risposta a message #40562] mer, 20 luglio 2011 22:38 Messaggio precedenteMessaggio successivo
Alessandro Selli  è attualmente disconnesso Alessandro Selli
Messaggi: 242
Registrato: novembre 2010
Senior Member
BIG (Umberto) ha scritto:

[...]

> Potesse essere (sono su debian)?
> big@debian:/tmp$ bash --version
> GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)
> Copyright (C) 2007 Free Software Foundation, Inc.

No, ho sbagliato io. L'esempio che ho copincollato sembrava
funzionare perché la variabile STDIN (che, tra parentesi, avrei dovuto
chiamare STDOUT) era stata inizializzata al valore "pippo" da una
precedente prova. In realtà quello che succede nel codice che segue:

STDOUT=$(ls pippo pluto 2> stderr) & STDERR=$(cat stderr)

è che il comando di attribuzione di valore a variabile STDOUT=$(ls pippo
pluto 2> stderr) & , eseguito in background, è eseguito in una
sottoshell mandata automaticamente in esecuzione dalla shell in cui è
eseguito lo script (o la shell del terminale, se il comando è eseguito
in modalità interattiva). Essendo le variabili confinate ad esistere
solamente nella shell in cui sono generate o, nel caso delle variabili
esportate, in quelle figlie ma mai in quelle genitrici, il valore di
STDOUT è perso.

Non mi viene in mente soluzione senza usare un file temporaneo al
posto della named pipe, quindi come rimedio ho da proporre solo queste
modifiche al tuo script adesso:

#!/bin/bash
clear
touch pippo
echo
STDOUT=$(ls pippo pluto 2> stderr)
status=$?
STDERR=$(< stderr)
echo status=$status
echo ===[$STDERR]
echo ===[$STDOUT]
echo
rm stderr


Ciao,


--
Alessandro Selli http://alessandro.route-add.net
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.
Re: Bash - stdout e stderr su 2 variabili [messaggio #40565 è una risposta a message #40564] mer, 20 luglio 2011 23:02 Messaggio precedenteMessaggio successivo
BIG (Umberto)  è attualmente disconnesso BIG (Umberto)
Messaggi: 9
Registrato: luglio 2011
Junior Member
Alessandro Selli in data Wednesday 20 July 2011 22:38, nel gruppo
it.comp.os.linux.iniziare ha scritto:

> No, ho sbagliato io. L'esempio che ho copincollato sembrava
> funzionare perché la variabile STDIN (che, tra parentesi, avrei dovuto
> chiamare STDOUT) era stata inizializzata al valore "pippo" da una
> precedente prova. In realtà quello che succede nel codice che segue:

> Non mi viene in mente soluzione senza usare un file temporaneo al
> posto della named pipe, quindi come rimedio ho da proporre solo queste
> modifiche al tuo script adesso:

Che risolve il problema, ed inoltre permette di avere il result status utile
per sapere come comportarsi.
Ottimo!

Grazie!!!!

--
+----------------------------------------------------------- ----------------+
| Avevo un lavoro, un posto fisso che mi rendeva bene e ci mantenevo tutta |
| la famiglia. Poi un giorno e' arrivato un tale, che mi ha detto: |
| Lazzaro, alzati e cammina! Da quel momento ho perso il posto, il lavoro e |
| sono finito in miseria. |
+-----#30--------------------Campagna contro le pubblicita` idiote.---------+
Re: Bash - stdout e stderr su 2 variabili [messaggio #40611 è una risposta a message #40564] sab, 23 luglio 2011 19:37 Messaggio precedente
BIG (Umberto)  è attualmente disconnesso BIG (Umberto)
Messaggi: 9
Registrato: luglio 2011
Junior Member
Alessandro Selli in data Wednesday 20 July 2011 22:38, nel gruppo
it.comp.os.linux.iniziare ha scritto:

> Non mi viene in mente soluzione senza usare un file temporaneo al
> posto della named pipe, quindi come rimedio ho da proporre solo queste
> modifiche al tuo script adesso:
>
> #!/bin/bash
> clear
> touch pippo
> echo
> STDOUT=$(ls pippo pluto 2> stderr)
> status=$?
> STDERR=$(< stderr)
> echo status=$status
> echo ===[$STDERR]
> echo ===[$STDOUT]
> echo
> rm stderr

Meglio a questo punto mettere all'inizio:
TMPFILE=$(mktemp)
ed usare al posto di stderr, $TMPFILE


--
+----------------------------------------------------------- ----------------+
| LA FIGA E' IL POSTO PIU' PULITO DEL MONDO PERCHE' CI SCOPANO TUTTI.. |
| MA ANCHE IL POSTO PIU' SERIO DEL MONDO |
+-----#36--------------------Campagna contro le pubblicita` idiote.---------+
Argomento precedente:Boot Ubuntu
Argomento successivo:Notebook HP 630
Vai al forum:
  


Ora corrente: mer apr 24 16:12:59 CEST 2024

Tempo totale richiesto per generare la pagina: 0.00958 secondi
.:: Contatti :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Live Support