2013-02-20 16 views
8

Mam skrypt, w którym muszę wyświetlić polecenie użycia w przypadku pominięcia przez użytkownika jakichkolwiek obowiązkowych informacji podczas wykonywania skryptu.Dodaj zawartość użycia w skrypcie powłoki bez getopts

Usage : Script -s <server> -i <instance> -u <user> -p <password> <query> -w <warning value> -c <critical value> 

Z wyjaśnień dotyczących wszystkich OPTIONS

Dostaję wartości z argumentów jak poniżej zmiennych mody. Ale chcę tego użycia z walidacjami w skrypcie powłoki.

SERVER=$1 
INSTANCE=$2 
USER=$3 
DB_PASSWD=$4 
QUERY=$5 
VAL_WARN=$6 
VAL_CRIT=$7 

Próbowałem przy użyciu getopts, ale nie udało się wykorzystać od <query> nie posiada parametr -q przed przekazaniem wartości.

Próbowałem znaleźć wszystkie inne sposoby, ale wszyscy sugerowali getopts, który nie jest rozwiązaniem dla mnie.

Proszę mi pomóc w tej sprawie ..

+1

Jedną z zalet listów opcji jest to, że pozwala użytkownikowi umieścić elementy w dowolnej kolejności. Jeśli zamówienie zostanie naprawione, nie ma potrzeby przejmowania się opcjami takimi jak '-s'; to sprawia, że ​​typ użytkownika jest dodatkiem, ponieważ zasadniczo nie przynosi żadnych korzyści. Zauważam, że łańcuch serwera to '$ 2' (nie' $ 1') w surowym wierszu poleceń. Czy nie możesz uregulować swojego polecenia, aby '-q' był potrzebny, lub aby zapytanie było ostatnim argumentem? Czy którakolwiek z opcji ma rozsądne wartości domyślne? Jeśli tak, użyj ich zamiast wymagać, aby użytkownik wpisze 13 argumentów. Twoi użytkownicy będą Ci wdzięczni, a Twój skrypt będzie łatwiejszy do napisania. –

Odpowiedz

20

Użyj klawiszy SHIFT iterację wszystkich swoich argumentów, coś takiego:

#!/bin/sh 

usage() 
{ 
    echo 'Usage : Script -s <server> -i <instance> -u <user> -p <password>' 
    echo '     <query> -w <warning value> -c <critical value>' 
    exit 
} 

if [ "$#" -ne 13 ] 
then 
    usage 
fi 

while [ "$1" != "" ]; do 
case $1 in 
     -s)   shift 
         SERVER=$1 
         ;; 
     -i)   shift 
         INSTANCE=$1 
         ;; 
     -u)   shift 
         USER=$1 
         ;; 
     -p)   shift 
         PASSWORD=$1 
         ;; 
     -w)   shift 
         WARNINGVAL=$1 
         ;; 
     -c)   shift 
         CRITICVAL=$1 
         ;; 
     *)   QUERY=$1 
    esac 
    shift 
done 

# extra validation suggested by @technosaurus 
if [ "$SERVER" = "" ] 
then 
    usage 
fi 
if [ "$INSTANCE" = "" ] 
then 
    usage 
fi 
if [ "$USER" = "" ] 
then 
    usage 
fi 
if [ "$PASSWORD" = "" ] 
then 
    usage 
fi 
if [ "$QUERY" = "" ] 
then 
    usage 
fi 
if [ "$WARNINGVAL" = "" ] 
then 
    usage 
fi 
if [ "$CRITICVAL" = "" ] 
then 
    usage 
fi 

echo "ALL IS WELL. SERVER=$SERVER,INSTANCE=$INSTANCE,USER=$USER,PASSWORD=$PASSWORD,QUERY=$QUERY,WARNING=$WARNINGVAL,CRITIC=$CRITICVAL" 

powinno załatwić sprawę.

EDIT: dodany walidacja argumentu w skrypcie jak sugeruje @technosaurus

+0

wymaga jedynie sprawdzenia na końcu '[! "$ PASSWORD"] && use' # i podobne dla innych obowiązkowych argumentów: – technosaurus

+0

@technosaurus AFAICS, które to zaznaczenie już istnieje: 'while [" $ 1 "! =" "] ...' –

+0

to nadal działałoby' skrypt q q q q q q q q q q q q q' i żadna z wymaganych wartości nie byłaby ustawiona na – technosaurus

1

getopts jest skarżenie na good reason. powinieneś zmienić interfejs skryptu, aby dostosować się do oczekiwań ludzi.

Alternatywnie, można dwukrotnie użyć getopts, najpierw dla opcji pre-query, shift, a następnie dla pozostałych.

1

to wypróbować

usage() 
{ 
    echo "$0 -s <server> -i <instance> -u <user> -p <password> <query> -w <warning value> -c <critical value>" 
} 

for i in {0..12} 
do 
    arg=`expr $i +1` 
    test ! "${!arg}" && usage && break 
done 

nadzieję, że to pomaga

+1

lub możesz "dla mnie w {1..13}' i pozbyć się podpowłoki. –

0

To niestandardowe podejście, ale taki, który uważam za bardzo przydatne. Zamiast przekazywać wartości jako argumenty do określonych flag (co jest dość denerwujące, użytkownik nie powinien być zobowiązany do podania każdej wartości, ale należy podać rozsądne wartości domyślne), można po prostu przekazać je bezpośrednio przez środowisko, tak aby wyglądało typowe wywołanie na przykład:

SERVER=blah INSTANCE=foo Script 

Byłoby miło, gdybyś użył nazwy zmiennej pisanej małymi literami, aby użytkownik nie musiał krzyczeć. Pozwala to skryptowi po prostu uniknąć całkowicie parsowania wiersza poleceń, ponieważ wartości zmiennych zostaną ustawione po rozpoczęciu skryptu.