[Risolto] getopt prende la seconda opzione come argomento

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
rai
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2848
Iscrizione: domenica 11 maggio 2008, 18:03
Desktop: plasma
Distribuzione: 22.04
Località: Palermo

[Risolto] getopt prende la seconda opzione come argomento

Messaggio da rai »

Dopo la lettura di una recente discussione ho dato una guardata a getopt ( da util-linux 2.20.1 ) e ho una difficoltà da superare col vostro aiuto.
Dato un esempio minimale come questo

Codice: Seleziona tutto

#!/bin/bash

# valori iniziali
val_A=False
val_B=False

# lettura delle opzioni
# `a'  ha argomento obbligatorio (ma non cambia renderlo facoltativo)
# `b'  non prevede argomento.
OPZIONI=`getopt -o a:b -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
eval set -- "$OPZIONI"

# In base alle opzioni, modifica le variabili.
while true ; do
    case "$1" in
        -a) val_A=$2; shift 2;;
        -b) val_B=True; shift  ;;
        --) shift ; break ;;
        *) echo "Internal error!" ; exit 1 ;;
    esac
done

echo "val_A = $val_A"
echo "val_B = $val_B"
se l'argomento della prima opzione per errore viene omesso nella riga del comando, getopt non si scompone e prende la successiva opzione come argomento

Codice: Seleziona tutto

$ /tmp/getopt-tmp -a-b
val_A = -b
val_B = False

$ /tmp/getopt-tmp -ab
val_A = b
val_B = False

$ /tmp/getopt-tmp -a -b
val_A = -b
val_B = False
Spoiler
Mostra
comunque, se si modifica lo script rendendo l'argomento della prima opzione facoltativo, solo se la seconda opzione è staccata il comportamento è quello previsto)

Codice: Seleziona tutto

$ /tmp/getopt-tmp -a -b
val_A = 
val_B = True

$ /tmp/getopt-tmp -a-b
val_A = -b
val_B = False

$ /tmp/getopt-tmp -ab
val_A = b
val_B = False
Devo capire qualcosa che mi sfugge di getopt o l'unico modo è gestire a mano ogni possibile errore con case e if annidati?
qualcosa di questo tipo?

Codice: Seleziona tutto

...
while true ; do
    case "$1" in
        -a)
           if [[ $2 =~ ^- ]]; then echo "missing argument -- \"a\""; exit 1; fi
...
Grazie anticipate
Ultima modifica di rai il sabato 12 settembre 2015, 23:34, modificato 1 volta in totale.
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: getopt prende la seconda opzione come argomento della pr

Messaggio da vbextreme »

non va confrontata la posizione ma il tipo di opzione.
Se premi sulla mia firma "bigt"(riga 82) vedi come gestire gli argomenti sia in formato breve che lungo.
Easy framework per il linguaggio C.
vbextreme hack your life
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: getopt prende la seconda opzione come argomento della pr

Messaggio da crap0101 »

non ti sfugge niente, è getopt che funziona così... non fa controlli per eventuali errori dell'utente, anche perchè sarebbe difficile distinguerli. Ad esempio la tua `-b` potrebbe essere sì un errore ma potrebbe anche essere lecitamente l'argomento di `-a`.
Sullo scriverle attaccate ( -ab ) è lo stesso discorso, lo puoi fare solo per quelle opzioni che non accettano argomenti (neanche opzionali).
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
rai
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2848
Iscrizione: domenica 11 maggio 2008, 18:03
Desktop: plasma
Distribuzione: 22.04
Località: Palermo

Re: getopt prende la seconda opzione come argomento della pr

Messaggio da rai »

Grazie delle risposte
vbextreme ha scritto:non va confrontata la posizione ma il tipo di opzione.
non ti seguo :-) nel codice che ho postato i parametri non sono posizionali.
Inoltre non mi pare che nel tuo script usi getopt per parsare le opzioni, né ci trovo qualche altro artificio che mette al riparo dal problema di quando un argomento atteso viene omesso per errore dalla riga di comando.
(confesso di avere solo letto lo script gbt: non mi funziona ma questo è un altro discorso)
crap0101 ha scritto:è getopt che funziona così... non fa controlli per eventuali errori dell'utente
quindi se lo script deve avere più utenti bisogna coprire manualmente anche l'eventuale errore umano.
Ovviamente era chiedere troppo distinguere programmaticamente una stringa `opzione' da una `argomento' a meno di sapere qualcosa di più sugli argomenti ammessi.
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: getopt prende la seconda opzione come argomento della pr

Messaggio da crap0101 »

Sì, tra l'altro mi sembra che molti programmi non facciano particolare attenzione a eventuali errori dell'utente... un pò perchè alcuni sono indecidibili, un pò perchè... bho, se sbaglia son c**** suoi :-D . Di controlli un pò più raffinati se ne possono comunque fare ma appunto son cose che generalmente vanno implementate separatamente, a meno di non usare lib apposite; sul momento mi viene in mente il modulo argparse di python con cui puoi, ad esempio, specificare il tipo dell'argomento, per cui se l'opzione si aspetta un int e tu gli passi una stringa che non può essere correttamente interpretata come un int, blocca il parsing e ti segnala l'errore.
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 11 ospiti