Я пытаюсь создать сценарий оболочки, который принимает различные параметры и getopts
кажется хорошим решением, так как он может обрабатывать переменное упорядочение параметров и аргументов (я думаю!).
Я буду использовать только короткие опции, и каждому короткому варианту потребуется соответствующее значение, например: ./command.sh -a arga -g argg -b argb
но я бы хотел, чтобы параметры вводились в неконкретном порядке, так как большинство людей привыкли работать с командами оболочки ,
Другой момент заключается в том, что я хотел бы сделать свою собственную проверку значений аргумента option, в идеале внутри case
операторов. Причина этого в том, что мое тестирование :)
в моем case
утверждении дало противоречивые результаты (вероятно, из-за отсутствия понимания с моей стороны).
Например:
#!/bin/bash
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
;;
u)
MYSQL_USER=$OPTARG
;;
p)
MYSQL_PASS=$OPTARG
;;
d)
BACKUP_DIR=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
:)
echo "Option -$OPTARG requires an argument" >&2
exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
Не удалось для подобных случаев ... ./command.sh -d -h
Когда я хочу, чтобы он пометил -d как требующий аргумента, но я получаю значение, -d=-h
которое не то, что мне нужно.
Поэтому я подумал, что было бы проще выполнить мою собственную проверку в операторах case, чтобы убедиться, что каждая опция установлена и установлена только один раз.
Я пытаюсь сделать следующее, но мои if [ ! "$MYSQL_HOST" ]; then
блоки не срабатывают.
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
if [ ! "$MYSQL_HOST" ]; then
echo "host not set"
exit 2
fi
;;
u)
MYSQL_USER=$OPTARG
if [ ! "$MYSQL_USER" ]; then
echo "username not set"
exit 2
fi
;;
p)
MYSQL_PASS=$OPTARG
if [ ! "$MYSQL_PASS" ]; then
echo "password not set"
exit 2
fi
;;
d)
BACKUP_DIR=$OPTARG
if [ ! "$BACKUP_DIR" ]; then
echo "backup dir not set"
exit 2
fi
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
#:)
# echo "Option -$opt requires an argument" >&2
# exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
Есть ли причина, по которой я не могу проверить, OPTARG
имеет ли an нулевую длину изнутри getopts ... while ... case
?
Какой лучший способ запустить мою собственную проверку аргументов getopts
в случае, когда я не хочу полагаться на :)
. Выполнить проверку моего аргумента за пределами while ... case ... esac
?
Тогда я мог бы получить значения аргументов и -d
т. Д. И не уловить пропущенную опцию.
while
цикл, работающий над опциями. Это метод, с которым я столкнулся, хотя он многословен по сравнению с другими, очень ясно, что происходит в сценарии. И ремонтопригодность других важна в этом случае.