bash subshell: exit vs return

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5182
Iscritto il: ven giu 02, 2006 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

bash subshell: exit vs return

Messaggioda ZeroUno » lun lug 22, 2019 17:18

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
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

hashbang
Packager
Packager
Messaggi: 1975
Iscritto il: ven giu 04, 2010 10:27
Nome Cognome: Luca De Pandis
Distribuzione: macOS Catalina
Località: Lecce / Bergamo / Milano
Contatta:

Re: bash subshell: exit vs return

Messaggioda hashbang » mar lug 23, 2019 16:49

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.

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5182
Iscritto il: ven giu 02, 2006 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: bash subshell: exit vs return

Messaggioda ZeroUno » mar lug 23, 2019 18:43

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.
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
lablinux
Linux 4.x
Linux 4.x
Messaggi: 1124
Iscritto il: gio nov 27, 2008 12:23
Desktop: Gnome
Distribuzione: Debian testing
Località: Rho

Re: bash subshell: exit vs return

Messaggioda lablinux » gio lug 25, 2019 15:16

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ù.

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5182
Iscritto il: ven giu 02, 2006 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: bash subshell: exit vs return

Messaggioda ZeroUno » gio lug 25, 2019 16:39

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.
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
lablinux
Linux 4.x
Linux 4.x
Messaggi: 1124
Iscritto il: gio nov 27, 2008 12:23
Desktop: Gnome
Distribuzione: Debian testing
Località: Rho

Re: bash subshell: exit vs return

Messaggioda lablinux » gio lug 25, 2019 16:51

"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)

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5182
Iscritto il: ven giu 02, 2006 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: bash subshell: exit vs return

Messaggioda ZeroUno » gio lug 25, 2019 17:07

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.
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6527
Iscritto il: gio nov 03, 2005 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: bash subshell: exit vs return

Messaggioda targzeta » gio lug 25, 2019 19:18

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà 

Avatar utente
lablinux
Linux 4.x
Linux 4.x
Messaggi: 1124
Iscritto il: gio nov 27, 2008 12:23
Desktop: Gnome
Distribuzione: Debian testing
Località: Rho

Re: bash subshell: exit vs return

Messaggioda lablinux » ven lug 26, 2019 8:39

[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]

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6527
Iscritto il: gio nov 03, 2005 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: bash subshell: exit vs return

Messaggioda targzeta » ven lug 26, 2019 19:51

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà 

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5182
Iscritto il: ven giu 02, 2006 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: bash subshell: exit vs return

Messaggioda ZeroUno » ven lug 26, 2019 20:04

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
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
lablinux
Linux 4.x
Linux 4.x
Messaggi: 1124
Iscritto il: gio nov 27, 2008 12:23
Desktop: Gnome
Distribuzione: Debian testing
Località: Rho

Re: bash subshell: exit vs return

Messaggioda lablinux » ven lug 26, 2019 23:16

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

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5182
Iscritto il: ven giu 02, 2006 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: bash subshell: exit vs return

Messaggioda ZeroUno » ven lug 26, 2019 23:33

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:
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
lablinux
Linux 4.x
Linux 4.x
Messaggi: 1124
Iscritto il: gio nov 27, 2008 12:23
Desktop: Gnome
Distribuzione: Debian testing
Località: Rho

Re: bash subshell: exit vs return

Messaggioda lablinux » sab lug 27, 2019 0:47

=D> =D> =D>