PDA

View Full Version : [aiuto per esame] comando shell getops


aeroxr1
03-04-2013, 09:03
ciao,
ho un dubbio ! A cosa servono i due punti in getopts . Cioè :

tra

getopts “:ab:c” OPTION

getopts abc OPTION

cosa cambia ?

Spero possiate darmi una mano ! :help:

airon
03-04-2013, 09:55
Ciao,

i : servono per dire a getopts che ciò che c'é dopo è l'argomento dell'opzione passata. Esempio:

getopts ab:c vuol dire che c è l'argomento dell'opzione b

comando -a -b y (getopts ab:y)

I : possono essere prima di tutto (getopts :ab:c): in questo caso attivi il silent mode (quindi niente erorri a schermo e messaggi, utile in produzione...)

Spero sia chiaro :)

aeroxr1
03-04-2013, 10:09
Grazie ! :)
Quindi getops ab:c vuol dire che volendo posso fare
comanda -a -b c
o
comando -a
o
comando -b c

giusto ?

Ho un altra domanda relativa ai comandi shell :)

devo fare un piccolo esercizio dove controllare ogni 30 secondi se l'utente passato come argomento abbia eseguito il logout
Io ho scritto questo :
#!/bin/bash

UTENTE=$1 #utente passato per argomento

while [ true ]; do
who | grep -c $UTENTE
if [ $? -eq 0 ];then
break
else
echo "loggato ancora"
sleep 5
continue
fi
done
echo "$UTENTE logout"

pensando che $? mi desse il risultato del comando precedente .
Ma con mio stupore mettendo un echo $? prima dell'if mi sono reso conto che ciò che viene stampato da $? è 1 e non il risultato del comando precedente che è 0 .

Cosa sbaglio ?

kwb
03-04-2013, 10:23
Grazie ! :)
Ho un altra domanda relativa ai comandi shell :)

devo fare un piccolo esercizio dove controllare ogni 30 secondi se l'utente passato come argomento abbia eseguito il logout
Io ho scritto questo :
#!/bin/bash

UTENTE=$1 #utente passato per argomento

while [ true ]; do
who | grep -c $UTENTE
if [ $? -eq 0 ];then
break
else
echo "loggato ancora"
sleep 5
continue
fi
done
echo "$UTENTE logout"

pensando che $? mi desse il risultato del comando precedente .
Ma con mio stupore mettendo un echo $? prima dell'if mi sono reso conto che ciò che viene stampato da $? è 1 e non il risultato del comando precedente che è 0 .

Cosa sbaglio ?

E se invece di usare $? ( che tra l'altro non so se sia appropriato ), salvassi il risultato del who | grep -c $1 dentro una variabile e controllassi questa?
risultato=`who | grep -c $1`

EDIT: Tra l'altro, io ho provato il comando sul mio portatile ( Macbook Pro ) e se do prima il who-grep e poi un echo $? mi ritorna 0 ( quindi nessun errore ).
In realtà $? ritorna il return status della funzione chiamata: grep ritorna 0 se non ci sono stati errori, 1 se nessun match è stato trovato. 2 in caso di errore.

Normally, exit status is 0 if selected lines are found and 1 otherwise. But the exit status is 2 if an error occurred, unless the -q or --quiet or --silent option is used and a selected line is found.

airon
03-04-2013, 10:32
Grazie ! :)
Quindi getops ab:c vuol dire che volendo posso fare
comanda -a -b c
o
comando -a
o
comando -b c

giusto ?



Si giusto.


Ho un altra domanda relativa ai comandi shell :)

devo fare un piccolo esercizio dove controllare ogni 30 secondi se l'utente passato come argomento abbia eseguito il logout
Io ho scritto questo :
#!/bin/bash

UTENTE=$1 #utente passato per argomento

while [ true ]; do
who | grep -c $UTENTE
if [ $? -eq 0 ];then
break
else
echo "loggato ancora"
sleep 5
continue
fi
done
echo "$UTENTE logout"

pensando che $? mi desse il risultato del comando precedente .
Ma con mio stupore mettendo un echo $? prima dell'if mi sono reso conto che ciò che viene stampato da $? è 1 e non il risultato del comando precedente che è 0 .

Cosa sbaglio ?

$? restituisce l'exit status del comando.
Il tuo script funziona in modo inverso da come pensi tu.
who | grep -c $UTENTE stampa il numero di righe per ogni $UTENTE loggato. Quindi 0 se l'utente non è loggato, 1 se è loggato 1 volta, 2 se è loggato 2, e cos' via.

Quindi se al posto di -eq metti -ne funziona come dovrebbe.

Comunque come ha detto Kwb salva il risultato del who | grep in una variabile. $1 in questo caso funziona perchè (credo) sia in una pipe con un counting.

Ciaoo

aeroxr1
03-04-2013, 10:36
grazie mille di tutto :)
siete stati chiarissimi !

kwb
03-04-2013, 10:40
$? restituisce l'exit status del comando.
Il tuo script funziona in modo inverso da come pensi tu.
who | grep -c $UTENTE stampa il numero di righe per ogni $UTENTE loggato. Quindi 0 se l'utente non è loggato, 1 se è loggato 1 volta, 2 se è loggato 2, e cos' via.

Mmm in realtà penso che stampi 0 se l'output di who | grep -c $user è >= 1 perchè, come ho indicato, grep restituisce 0 se trova il match.
Quello che dovrebbe fare lui è controllare che il risultato sia uguale a 1 ( grep non ha trovato nessun match ) e non 0.

airon
03-04-2013, 10:52
Grazie ! :)
Quindi getops ab:c vuol dire che volendo posso fare
comanda -a -b c
o
comando -a
o
comando -b c

giusto ?

Ho un altra domanda relativa ai comandi shell :)

devo fare un piccolo esercizio dove controllare ogni 30 secondi se l'utente passato come argomento abbia eseguito il logout
Io ho scritto questo :
#!/bin/bash

UTENTE=$1 #utente passato per argomento

while [ true ]; do
who | grep -c $UTENTE
if [ $? -eq 0 ];then
break
else
echo "loggato ancora"
sleep 5
continue
fi
done
echo "$UTENTE logout"

pensando che $? mi desse il risultato del comando precedente .
Ma con mio stupore mettendo un echo $? prima dell'if mi sono reso conto che ciò che viene stampato da $? è 1 e non il risultato del comando precedente che è 0 .

Cosa sbaglio ?

Mmm in realtà penso che stampi 0 se l'output di who | grep -c $user è >= 1 perchè, come ho indicato, grep restituisce 0 se trova il match.
Quello che dovrebbe fare lui è controllare che il risultato sia uguale a 1 ( grep non ha trovato nessun match ) e non 0.

Si hai ragione, ho fatto una prova.
$? ha 0 se grep -c ha come risultato un match (quindi almeno una riga, quindi utente loggato) mentre 1 se non ha trovato utenti.

aeroxr1
03-04-2013, 11:26
si anche secondo me se metto in una variabile evito ambiguità :

risultato=`who | grep -c $1`

e poi controllo che questa variebile sia uguale a zero con -eq e dovrei essere apposto no ? :)


un ultimissimo dubbio :

in un case su opzioni getopt ace opt

se voglio accettare anche la possibilità di concatenare le azioni di tutte e 3 le opzioni :

cioè

while getopts ace opt
do
case "$opt" in
a) stampa
c) giravolta
e) pluto
*) sbagliato
esac
done

se faccio

./comando -ace

ho come risultato stampa giravolta pluto giusto ? e ottengo questo risultato grazie al while ?

in una lezione il prof mise al posto di *) \?)
\? a cosa serve ?