2013-01-21 5 views
48

Sto cercando di fare uno script di shell che è stato progettato per essere eseguito in questo modo:Bash Shell Script - Verificare la presenza di una bandiera e afferrare il suo valore

script.sh -t application 

In primo luogo, nel mio script voglio verificare se lo script è stato eseguito con il flag -t. Per esempio se è stato eseguito senza il flag simili voglio che error:

script.sh 

secondo luogo, supponendo che non v'è un flag -t, voglio afferrare il valore e memorizzarlo in una variabile che posso utilizzare nel mio script per esempio come questo:

FLAG="application" 

Finora l'unico progresso sono stato in grado di fare in tutto questo è che $ @ afferra tutti gli argomenti della riga di comando, ma non so come questo si riferisce alle bandiere, o se questo è anche possibile.

+0

Eventuali duplicati di [Come fare Analizzo gli argomenti della riga di comando in bash?] (Http://stackoverflow.com/questions/192249/how-do-i-parse-command-line-argiments-in-bash) – Jaketr00

risposta

82

Si consiglia di leggere questo tutorial getopts.

Esempio con -a interruttore che richiede un argomento: (! getopt = getopts)

#!/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 greybot detto:

The external command getopt(1) is never safe to use, unless you know it is GNU getopt, you call it in a GNU-specific way, and you ensure that GETOPT_COMPATIBLE is not in the environment. Use getopts (shell builtin) instead, or simply loop over the positional parameters.

+0

Funziona anche per shell? – Jimmy

+1

'getopts' è un built-in' bash', ma esiste anche un programma 'getopt' esterno che dovrebbe funzionare con qualsiasi shell POSIX-compatibile. – chepner

+3

Il comando esterno getopt (1) non è mai sicuro da usare, a meno che tu non sappia * è GNU getopt, lo chiami in un modo specifico per GNU, * e * ti assicuri che GETOPT_COMPATIBLE non sia nell'ambiente. Usa invece getopts (shell builtin) o semplicemente loop sui parametri posizionali. –

22

Usa $# per afferrare il numero di argomenti, se è diverso a 2 non ci sono argomenti sufficienti forniti:

if [ $# -ne 2 ]; then 
    usage; 
fi 

Successivamente, verificare se $1 uguale -t, in caso contrario è stata utilizzata una bandiera sconosciuta:

if [ "$1" != "-t" ]; then 
    usage; 
fi 

memorizzare Infine $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 
} 
0

Prova shFlags - Libreria di flag di riga di comando avanzata per script di shell Unix.

http://code.google.com/p/shflags/

è molto buono e molto flessibile.

TIPI DI FLAG: 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 a una lettera). Alcuni flag hanno altri argomenti, che sono descritti con la bandiera.

DEFINE_string: accetta qualsiasi input e lo reimposta come una stringa.

DEFINE_boolean: in genere non accetta alcun argomento: ad esempio --myflag per impostare FLAGS_myflag su true o --nomyflag per impostare FLAGS_myflag su false. In alternativa, è possibile dire --myflag = true o --myflag = t o --myflag = 0 o --myflag = false o --myflag = f o --myflag = 1 Il passaggio di un'opzione ha lo stesso valore influenzare come passare l'opzione una volta.

DEFINE_float: prende un input e lo immette come numero in virgola mobile. Poiché la shell non supporta float per sé, l'input è semplicemente convalidato come come valore in virgola mobile valido.

DEFINE_integer: prende un input e lo reinterpreta come un numero intero.

flag speciali: Ci sono un paio di bandiere che hanno un significato speciale: --help (? O -) stampa un elenco di tutte le bandiere in modo leggibile --flagfile = foo leggere bandiere di foo. (Non ancora implementato) - come in getopt(), termina la bandiera di elaborazione

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 shflags