Є деякі вбудовані інструменти , які розпізнають -x
і --xxxx
як перемикачі, а не аргументи, або ж ви повинні пройти через всі вхідні змінні, тест на тир, а потім розібрати аргументи в подальшому?
Є деякі вбудовані інструменти , які розпізнають -x
і --xxxx
як перемикачі, а не аргументи, або ж ви повинні пройти через всі вхідні змінні, тест на тир, а потім розібрати аргументи в подальшому?
Відповіді:
Використовуйте getopts
.
Він досить портативний, як і в специфікації POSIX. На жаль, він не підтримує довгі варіанти.
Дивіться також цю getopts
підручник з люб'язності вікі-хакер-хакерів і це питання від stackoverflow.
Якщо вам потрібні лише короткі параметри, типовою схемою використання getopts
(з використанням беззвучного повідомлення про помилки) є:
# process arguments "$1", "$2", ... (i.e. "$@")
while getopts "ab:" opt; do
case $opt in
a) aflag=true ;; # Handle -a
b) barg=$OPTARG ;; # Handle -b argument
\?) ;; # Handle error: unknown option or missing required argument.
esac
done
while getopts "ab:" opt
?
:
після опції означає, що він вимагає аргументу. А :
як перший символ означає придушити повідомлення про помилки.
Я припускаю, що ви використовуєте bash або подібне. Приклад:
all=false
long=false
while getopts ":hal" option; do
case $option in
h) echo "usage: $0 [-h] [-a] [-l] file ..."; exit ;;
a) all=true ;;
l) long=true ;;
?) echo "error: option -$OPTARG is not implemented"; exit ;;
esac
done
# remove the options from the positional parameters
shift $(( OPTIND - 1 ))
ls_opts=()
$all && ls_opts+=( -a )
$long && ls_opts+=( -l )
# now, do it
ls "${ls_opts[@]}" "$@"
+=
з масивом. Не знав, що ти можеш це зробити. Приємно!
Ви повинні написати цикл для розбору параметрів. Дійсно, ви можете використовувати getopts
команду, щоб зробити це легко.
Це простий приклад зі getopts
сторінки керівництва:
aflag=
bflag=
while getopts ab: name
do
case $name in
a) aflag=1;;
b) bflag=1
bval="$OPTARG";;
?) printf "Usage: %s: [-a] [-b value] args\n" $0
exit 2;;
esac
done
if [ ! -z "$aflag" ]; then
printf "Option -a specified\n"
fi
if [ ! -z "$bflag" ]; then
printf 'Option -b "%s" specified\n' "$bval"
fi
shift $(($OPTIND - 1))
printf "Remaining arguments are: %s\n" "$*"
Нещодавно я написав сценарій для роботи, яка була універсальною і дозволяла виконувати різні види комутаторів у будь-якому порядку. Я не можу розкрити повний сценарій з очевидних юридичних причин (не кажучи вже про те, що на даний момент у мене його немає), але ось його м'ясо .. Ви можете помістити його в підпрограму і зателефонувати в кінці вашого сценарію:
options () {
if [ -n "$1" ]; then # test if any arguments passed - $1 will always exist
while (( "$#" )); do # process ALL arguments
if [ "$1" = ^-t$ ]; then # -t short for "test"
# do something here THEN shift the argument
# shift removes it from $@ and reduces $# by
# one if you supply no argument
shift
# we can also process multiple arguments at once
elif [[ "$1" =~ ^--test=[:alnum:]{1,8}$ ]] && [[ "$2" =~ ^-t2$ ]] && [[ -n "$3" ]]; then # check for 3 arguments
# do something more then remove them ALL from the arg list
shift 3
else
echo "No matching arguments!"
echo "Usage: [script options list here]"
fi
done
else
echo "Usage: [script options list here]"
exit 0
fi
}
options "$@" # run options and loop through/process ALL arguments
Я рекомендую обмежити ваш скрипт bash менше 400 рядків / 15 К символів; мій вищезгаданий сценарій переріс цей розмір і надто важко було працювати над. Я почав її переписувати в Perl, що набагато краще підходить для виконання завдання. Майте це на увазі, коли ви працюєте над своїми сценаріями в bash. Bash чудово підходить для невеликих сценаріїв та онлайнів, але все, що складніше, і вам краще написати це на Perl.
Зауважте, я не перевіряв вищесказане, тому, ймовірно, це не працює, але ви отримуєте з цього загальну думку.
options
в кінці телефонуєте, невірне, воно повернеться -bash: syntax error near unexpected token $@
. Називай це як options "$@"
.
while
умова не повинна бути (($#))
замість цього?
$#
? Редагувати: ти маєш рацію. Виправлено цеwhile (( "$#" ))
getopt
перед тим, як використовувати його, завжди слід перевіряти як GNU getopt, але все одно не слід користуватися ним, оскільки це все-такиgetopts
більш портативно (і взагалі приємніше). Якщо ви робите потреба назвати його по якій - то причини, називають його в GNU-певним чином, і переконайтеся , щоGETOPT_COMPATIBLE
це не в навколишньому середовищі.