Pagina 1 di 1

bash subshell: exit vs return

Inviato: lun lug 22, 2019 17:18
da ZeroUno
Ciao.
Come gestireste questa situazione?

Ho una funzione in bash che da il suo output in più modi contemporaneamente:
1) return code
2) standard output
3) export di variabili
in aggiunta a fronte di errori lancia un exit per l'abort dell'intero script

Codice: Seleziona tutto

function pippo(){
    if [ -z "$1" ];then
       echo "ABORT"
       exit 1
    fi
    out=$1
    echo paperino
    return 2
}
pippo ciao
echo $?
echo $out
pippo
echo end

stampa:

Codice: Seleziona tutto

paperino
2
ciao
ABORT

ed esce dal programma

ora, a volte il paperino va trappato in una variabile con a=$(pippo ciao).
ovviamente così mi perdo l'export di out in quanto subshell, ma mi perdo anche l'abort del programma (non la scritta ABORT) in quanto si trasforma in una return e viene trappato (o meglio, la return si trasforma in exit è più corretto).

Codice: Seleziona tutto

a=$(pippo ciao)
echo $?
echo $out
echo $a
b=$(pippo)
echo $?
echo $b
echo end

stampa

Codice: Seleziona tutto

2

paperino
1
ABORT
end

come gestireste la generazione di un vero abort? (cioè ad 'end' non ci dovrebbe arrivare)
mi sono venuti in mente diverse soluzioni, tutte sporche, ma vorrei sentire le vostre

Re: bash subshell: exit vs return

Inviato: mar lug 23, 2019 16:49
da hashbang
Io non capisco, onestamente, perché fai tornare la funzione con 2, che non è un EXIT_SUCCESS.
In sostanza stai dicendo in quello script che qualunque cosa succeda quella funzione, essa debba uscire sempre in errore.

Se la funzione infatti tornasse 0 in caso di successo, per ottenere il risultato sperato ti basterebbe utilizzare un banale "set -e".

Codice: Seleziona tutto

#!/bin/bash -e
function pippo(){
    if [ -z "$1" ];then
       echo "ABORT"
       return 1
    fi
    out=$1
    echo paperino
}
a=$(pippo ciao)
echo $?
echo $out
echo $a
b=$(pippo)
echo $?
echo $b
echo end

che giustamente stampa

Codice: Seleziona tutto

0

paperino


Per quanto riguarda la definizione della variabile $out, il concetto è IMHO sbagliato alla radice.
Una variabile non dovrebbe mai avere scope globale se definita all'interno di una funzione, in quanto quest'ultima è ad un livello logico inferiore rispetto al codice chiamante.
Difatti, io per mantenere un minimo di scoping decente, cerco sempre di gestire le variabili all'interno di una funzione dichiarandole local. Purtroppo, anche questo non basta, perché lo scoping di bash non funziona come dovrebbe, in quanto una variabile local è comunque global per le funzioni che vengono chiamate dalla funzione stessa.

Quello che voglio dire è che se il compito di $out è stampare l'argomento a schermo, senza che esso venga trappato dalle variabili $a e $b che in caso di successo dovrebbero solo trappare "paperino", ti conviene usare lo standard error, che poi è ciò che dovresti usare anche per ABORT, in quanto gli errori dovrebbero sempre andare in /dev/stderr e redirezionati in /dev/stdout all'occorrenza.

Ovvero:

Codice: Seleziona tutto

#!/bin/bash -e
function pippo(){
    if [ -z "$1" ];then
       echo "ABORT" > /dev/stderr
       return 1
    fi
    echo $1 > /dev/stderr
    echo paperino
}
a=$(pippo ciao)
echo $?
echo $a
b=$(pippo)
echo $?
echo $b
echo end

che stampa a schermo

Codice: Seleziona tutto

ciao
0
paperino
ABORT


Questo è come gestire occhio e croce il tuo esempio, senza stravolgere più di tanto il codice.
Naturalmente, se hai delle necessità tali per cui la funzione pippo() deve tornare necessariamente 2, allora si può gestire, ma IMHO faresti meglio a verificare se tale eccezione alla regola sia davvero necessaria, visto che rendi il codice meno pulito.

Re: bash subshell: exit vs return

Inviato: mar lug 23, 2019 18:43
da ZeroUno
Il problema è che bash pur avendo un sacco di costrutti della programmazione, è pur sempre un linguaggio orientato allo scripting con i sui limiti.
Per esempio le funzioni possono restituire solo return code. Non posso per esempio fare
a="ciao"
return $a
Quindi ci si adegua come si può.
$out è una stringa o altro proveniente dalla elaborazione della funzione e poi la chiamante se la assegna a quello che gli serve e fa unset out (nell'ultima versione è un array associativo che tra l'altro devo dichiarare esternamente prima di chiamare la funzione)
Il return code è qualcosa tipo il numero di righe di una tabella per esempio
Lo standard output può magari essere la tabella stessa.

Mi rendo conto che non è proprio utilizzare bash per scopi elaborati, ma a livello di programmazione è il mio massimo skill :) ed ho bisogno di fare un programma funzionante.

Contemporaneamente sto approfittando - solo come esercizio - a fare parallelamente lo stesso programma in python, linguaggio che poco conosco e poco mi piace ma che è opportuno che imparo, e questa è una buona occasione.

A bash gli mancano troppe cose che python ha, dagli oggetti, al trap degli errori di natura multipla, ecc.
Compensa con la sua semplicità e la mia conoscenza nettamente sbilanciata tra i due.

Poi vediamo quando ho finito il programma che funziona meglio :D
Il trap degli errori di multipla natura e la gestione delle eccezioni qui fa la differenza.


Per natura questo programma troverebbe buona implementazione in perl credo, ma non mi ci sono mai cimentato e tutti i programmi che ho fatto sono modifiche o merge di già esistenti.

Re: bash subshell: exit vs return

Inviato: gio lug 25, 2019 15:16
da lablinux
ZeroUno ha scritto: python, linguaggio che poco conosco e poco mi piace

:protest: :protest: :protest:

E' un piacere usralo e l'indentazione obbligatoria è una marcia in più.

Re: bash subshell: exit vs return

Inviato: gio lug 25, 2019 16:39
da ZeroUno
Nell'ultimo periodo ho fatto un corso.
Ho cominciato ad apprezzare le funzionalità e le strutture di programmazione che non conoscevo.
Questo ha in parte compensato la sintassi odiosa (non solo l'indentazione).
Contemporaneamente ho imparato le norme pep, che seppur facoltative hanno annullato la compensazione.

Il codice non è solo algoritmi. Il codice è arte.

Re: bash subshell: exit vs return

Inviato: gio lug 25, 2019 16:51
da lablinux
"Il codice non è solo algoritmi. Il codice è arte." e inizia dall'indentazione. E' dificile all'inizio ma poi è tutto un'altra cosa.
Cosa c'è nella sintassi che non ti piace? Non la trovo particolarmente diversa da altri linguaggi (prova ruby, magari lo apprezzi)

Re: bash subshell: exit vs return

Inviato: gio lug 25, 2019 17:07
da ZeroUno
L'arte comincia dove hai possibilità di scelta. Altrimenti è tecnica. Decido io se è il caso di andare a capo.
Pep addirittura mi mette i paletti nei commenti :O

Comunque riguardo le strutture logiche sta andando bene anche se ancora non le ho spremute come si deve.

Re: bash subshell: exit vs return

Inviato: gio lug 25, 2019 19:18
da targzeta
lablinux ha scritto:
ZeroUno ha scritto: python, linguaggio che poco conosco e poco mi piace

:protest: :protest: :protest:

E' un piacere usralo e l'indentazione obbligatoria è una marcia in più.

Offtopic: A me il fatto che i blocchi siano identificati solo dell'indentazione non mi piace per nulla nel Python. Perdi un'indentazione e sei fuori da un blocco!

Emanuele

Re: bash subshell: exit vs return

Inviato: ven lug 26, 2019 8:39
da lablinux
[OT]perditi una parentesi e vediamo, se hai mal indentato, quanto ci metti a ritrovati. Ho messo mano a programmi php scritti con i piedi dove ci sono blocchi di decinaia di righe, con all'interno condizioni e/o cicli... a volte indentati a volte no, a volte con un tab a volte con spazi. Buona parte di questi script li ho dovuti riscrivere per capirci qualcosa[/ot]

Re: bash subshell: exit vs return

Inviato: ven lug 26, 2019 19:51
da targzeta
Offtopic:
lablinux ha scritto:[OT]perditi una parentesi e vediamo, se hai mal indentato, quanto ci metti a ritrovati. Ho messo mano a programmi php scritti con i piedi dove ci sono blocchi di decinaia di righe, con all'interno condizioni e/o cicli... a volte indentati a volte no, a volte con un tab a volte con spazi. Buona parte di questi script li ho dovuti riscrivere per capirci qualcosa[/ot]
Avere i blocchi racchiusi tra graffe non vuol dire non indentare il codice. Se dimentichi una graffa, il programma non gira. Se indenti male una riga su python, quello fa una cosa diversa da quello che ti aspettavi.

Es:

Codice: Seleziona tutto

python -c 'i=0
while True:
 if i == 10:
  print "Fine ciclo infinito!"
 break
 i+=1'
Non da nessun errore ma non fa quello voluto perché il break è indentato male.

Codice: Seleziona tutto

perl -e '$i=0;
while (1) {
  if ($i == 10) {
    print "Fine ciclo infinito!";
  last;
  $i++;
}'
Restituisce

Codice: Seleziona tutto

Missing right curly or square bracket at -e line 7, at end of line
syntax error at -e line 7, at EOF
Execution of -e aborted due to compilation errors.

Poi considera che:
  • qualcuno indenta con gli spazi, qualcuno con i tab;
  • gli IDE permettono di spostare blocchi qua e là, su e già, un livello più a destra, uno più a sinistra. Se per errore un IDE sbaglia ad indentare un blocco che stai spostando, hai finito.
A mio avviso lo rende un linguaggio poco usabile.

Emanuele

Re: bash subshell: exit vs return

Inviato: ven lug 26, 2019 20:04
da ZeroUno
La scelta di un linguaggio è come la scelta di religione e la scelta politica. Ognuno mostrerà i vantaggi che ritiene tali e ognuno considererà vani i vantaggi che gli altri ritengono tali.
Quindi smettiamo questa guerra altrimenti ci dobbiamo autobannare :D

Re: bash subshell: exit vs return

Inviato: ven lug 26, 2019 23:16
da lablinux
Nessuna guerra per così poco. Poi sono dell'idea che è meglio conoscere più linguaggi ed utilizzare quello più adatto al lavoro che va svolto. Poi uno preferisce python e un altro Ruby o perl o Java o .net
C'è ne sono talmente tanti

Re: bash subshell: exit vs return

Inviato: ven lug 26, 2019 23:33
da ZeroUno
Comunque sto continuando il doppio sviluppo, bash e python.
Dopo le connessioni ldap sono arrivato a quelle oracle. Piccolo problema (superato) ho oracle 9 :shock:

Re: bash subshell: exit vs return

Inviato: sab lug 27, 2019 0:47
da lablinux
=D> =D> =D>