Il modo più comune di fare che sta assegnando gli argomenti di variabili locali nella funzione, vale a dire:
copy() {
local from=${1}
local to=${2}
# ...
}
Un'altra soluzione può essere getopt in stile parsing opzione.
copy() {
local arg from to
while getopts 'f:t:' arg
do
case ${arg} in
f) from=${OPTARG};;
t) to=${OPTARG};;
*) return 1 # illegal option
esac
done
}
copy -f /tmp/a -t /tmp/b
Purtroppo, bash non può gestire le opzioni lunghe che sarebbe essere più leggibile, vale a dire:
copy --from /tmp/a --to /tmp/b
Per questo, vi sia bisogno di usare il programma esterno getopt
(che Penso che abbia un lungo supporto opzionale solo sui sistemi GNU) o implementare il parser di opzioni lunghe a mano, ovvero:
copy() {
local from to
while [[ ${1} ]]; do
case "${1}" in
--from)
from=${2}
shift
;;
--to)
to=${2}
shift
;;
*)
echo "Unknown parameter: ${1}" >&2
return 1
esac
if ! shift; then
echo 'Missing parameter argument.' >&2
return 1
fi
done
}
copy --from /tmp/a --to /tmp/b
.210
Vedi anche: using getopts in bash shell script to get long and short command line options
Si può anche essere pigro, e solo passare i 'variabili' come argomenti alla funzione, vale a dire:
copy() {
local "${@}"
# ...
}
copy from=/tmp/a to=/tmp/b
e avrete ${from}
e ${to}
nella funzione come variabili locali.
Basta notare che si applica lo stesso problema di seguito: se una determinata variabile non viene passata, sarà ereditata dall'ambiente padre. Si consiglia di aggiungere una 'linea di sicurezza' come:
copy() {
local from to # reset first
local "${@}"
# ...
}
per garantire che ${from}
e ${to}
sarà impostata quando non è passato.
E se qualcosa molto male è di tuo interesse, si potrebbe anche assegnare gli argomenti come variabili globali quando si richiama la funzione, vale a dire:
from=/tmp/a to=/tmp/b copy
Allora si potrebbe utilizzare ${from}
e ${to}
all'interno della funzione copy()
. Basta notare che dovresti quindi sempre passare passare tutti i parametri. Altrimenti, una variabile casuale potrebbe infiltrarsi nella funzione.
from= to=/tmp/b copy # safe
to=/tmp/b copy # unsafe: ${from} may be declared elsewhere
Se si dispone di bash 4.1 (credo), si può anche provare a utilizzare array associativi. Ti permetterà di passare argomenti con nome ma è essere brutto. Qualcosa di simile:
args=([from]=/tmp/a [to]=/tmp/b)
copy args
E poi nel copy()
, avresti bisogno di grab the array.
Qual è la differenza tra l'utilizzo di '$ 1' vs' $ ARG1'? –
@JonLin: posso usare un nome più intuitivo, invece di $ 1, $ 2. I numeri sono confusi. – Bhushan
Hai davvero bisogno di sette parametri obbligatori? Un approccio comune sarebbe quello di trasformare il maggior numero possibile in opzioni e fornire un valore predefinito dove ha senso. Rende il tuo script molto più facile da usare se non si deve memorizzare un particolare ordine posizionale per un numero così grande di argomenti, anche se la maggior parte degli utenti sovrascrive i valori predefiniti per la maggior parte del tempo. – tripleee