Prova shFlags -- Libreria avanzata di flag da riga di comando per gli script della shell Unix.
http://code.google.com/p/shflags/
È molto buono e molto flessibile.
FLAG TIPI:Questa è una lista di DEFINE_* che puoi fare. Tutti i flag accettano un nome, un valore predefinito, una stringa di aiuto e un nome 'breve' facoltativo (nome di una lettera). Alcuni flag hanno altri argomenti, che sono descritti con il flag.
DEFINE_string:accetta qualsiasi input e lo interpreta come una stringa.
DEFINE_boolean:in genere non accetta alcun argomento:diciamo --myflag per setFLAGS_myflag su true, o --nomyflag per impostare FLAGS_myflag su false. In alternativa, puoi dire--myflag=true o --myflag=t o --myflag=0 o--myflag=false o --myflag=f o --myflag=1Passare un'opzione ha lo stesso effetto di passare l'opzione una volta.
DEFINE_float:prende un input e lo interpreta come un numero in virgola mobile. Asshell non supporta i float di per sé, l'input viene semplicemente convalidato come valore in virgola mobile valido.
DEFINE_integer:prende un input e lo interpreta come un numero intero.
FLAG SPECIALI:Ci sono alcuni flag che hanno un significato speciale:--help (o -?) stampa un elenco di tutti i flag in modo leggibile dall'uomo--flagfile=foo leggi i flag da foo. (non ancora implementato)-- come in getopt(), termina l'elaborazione dei flag
ESEMPIO DI UTILIZZO:
-- begin hello.sh --
! /bin/sh
. ./shflags
DEFINE_string name 'world' "somebody's name" n
FLAGS "[email protected]" || exit $?
eval set -- "${FLAGS_ARGV}"
echo "Hello, ${FLAGS_name}."
-- end hello.sh --
$ ./hello.sh -n Kate
Hello, Kate.
Nota:ho preso questo testo dalla documentazione di shflags
Ecco una semplice interfaccia di argomenti di comando generalizzata che puoi incollare in cima a tutti i tuoi script.
#!/bin/bash
declare -A flags
declare -A booleans
args=()
while [ "$1" ];
do
arg=$1
if [ "${1:0:1}" == "-" ]
then
shift
rev=$(echo "$arg" | rev)
if [ -z "$1" ] || [ "${1:0:1}" == "-" ] || [ "${rev:0:1}" == ":" ]
then
bool=$(echo ${arg:1} | sed s/://g)
booleans[$bool]=true
echo \"$bool\" is boolean
else
value=$1
flags[${arg:1}]=$value
shift
echo \"$arg\" is flag with value \"$value\"
fi
else
args+=("$arg")
shift
echo \"$arg\" is an arg
fi
done
echo -e "\n"
echo booleans: ${booleans[@]}
echo flags: ${flags[@]}
echo args: ${args[@]}
echo -e "\nBoolean types:\n\tPrecedes Flag(pf): ${booleans[pf]}\n\tFinal Arg(f): ${booleans[f]}\n\tColon Terminated(Ct): ${booleans[Ct]}\n\tNot Mentioned(nm): ${boolean[nm]}"
echo -e "\nFlag: myFlag => ${flags["myFlag"]}"
echo -e "\nArgs: one: ${args[0]}, two: ${args[1]}, three: ${args[2]}"
Eseguendo il comando:
bashScript.sh firstArg -pf -myFlag "my flag value" secondArg -Ct: thirdArg -f
L'output sarà questo:
"firstArg" is an arg
"pf" is boolean
"-myFlag" is flag with value "my flag value"
"secondArg" is an arg
"Ct" is boolean
"thirdArg" is an arg
"f" is boolean
booleans: true true true
flags: my flag value
args: firstArg secondArg thirdArg
Boolean types:
Precedes Flag(pf): true
Final Arg(f): true
Colon Terminated(Ct): true
Not Mentioned(nm):
Flag: myFlag => my flag value
Args: one => firstArg, two => secondArg, three => thirdArg
Fondamentalmente, gli argomenti sono divisi in flag booleani e argomenti generici. In questo modo un utente può mettere i flag e i booleani ovunque purché mantenga gli argomenti generici (se ce ne sono) nell'ordine specificato.
Permettendo a me e ora a te di non occuparci mai più dell'analisi degli argomenti di bash!
Puoi visualizzare uno script aggiornato qui
Questo è stato enormemente utile nell'ultimo anno. Ora può simulare l'ambito anteponendo alle variabili un parametro di ambito.
Basta chiamare lo script come
replace() (
source $FUTIL_REL_DIR/commandParser.sh -scope ${FUNCNAME[0]} "[email protected]"
echo ${replaceFlags[f]}
echo ${replaceBooleans[b]}
)
Non sembra che io abbia implementato l'ambito dell'argomento, non sono sicuro del motivo per cui immagino di non averne ancora bisogno.
Usa $#
per afferrare il numero di argomenti, se è diverso da 2 non ci sono abbastanza argomenti forniti:
if [ $# -ne 2 ]; then
usage;
fi
Successivamente, controlla se $1
equivale a -t
, altrimenti è stato utilizzato un flag sconosciuto:
if [ "$1" != "-t" ]; then
usage;
fi
Infine memorizza $2
in FLAG
:
FLAG=$2
Nota:usage()
è una funzione che mostra la sintassi. Ad esempio:
function usage {
cat << EOF
Usage: script.sh -t <application>
Performs some activity
EOF
exit 1
}
Dovresti leggere questo tutorial su getopts.
Esempio con -a
switch che richiede un argomento :
#!/bin/bash
while getopts ":a:" opt; do
case $opt in
a)
echo "-a was triggered, Parameter: $OPTARG" >&2
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
Come ha detto greybot(getopt
!=getopts
) :
Il comando esterno getopt(1) non è mai sicuro da usare, a meno che tu non lo sappia è GNU getopt, lo chiami in un modo specifico di GNU, e ti assicuri che GETOPT_COMPATIBLE non sia nell'ambiente. Usa invece getopts (shellbuiltin) o semplicemente esegui il loop sui parametri posizionali.