Да, Вы можете. Страницы справочника записаны как nroff файлы.
/usr/local/man каталог является местоположением, обычно используемым для любых локально установленных пакетов/файлов.
Можно посмотреть на примеры путем рассмотрения существующих страниц справочника, (который должен будет, вероятно, быть несжатым сначала), также считайте человека.
В настоящее время многие пользователи предпочитают groff nroff, man groff
начать
Когда Вы называете свой второй сценарий (я сохранил его как getoptit
) с:
getoptit -d -h
Это распечатает:
MYSQL_HOST='' MYSQL_USER='' MYSQL_PASS='' BACKUP_DIR='-h' Additionals:
Таким образом, BACKUP_DIR установлен, и Вы тестируете с if [ ! "$BACKUP_DIR" ]; then
если это не установлено, таким образом, нормально, что код в нем не инициирован.
Если Вы хотите протестировать, если каждая опция установлена однажды, необходимо сделать это, прежде чем Вы сделаете присвоение от значения $OPTARG. И необходимо, вероятно, также проверить на $OPTARG для запуска с a '-'
(для -d -h
ошибка) перед присвоением:
...
d)
if [ ! -z "$BACKUP_DIR" ]; then
echo "backup dir already set"
exit 2
fi
if [ z"${OPTARG:0:1}" == "z-" ]; then
echo "backup dir starts with option string"
exit 2
fi
BACKUP_DIR=$OPTARG
;;
...
Так как другие ответы на самом деле не отвечают на Ваш вопрос так: Это - ожидаемое поведение и на основе того, как POSIX интерпретируется:
Когда опция потребует аргумента опции, getopts утилита должна поместить ее в переменную оболочки OPTARG. Если никакая опция не была найдена, или если опция, которая была найдена, не будет иметь аргумента опции, то OPTARG должен быть сброшен.)
Это - все, что указывается, и помещать (не так долго) короткая история: getopts
волшебно не знает, что совершенно допустимым аргументом, он видит опцию, которой Вы требуете, чтобы иметь аргумент, является на самом деле не аргумент опции, но другая опция. Ничто не препятствует тому, чтобы Вы имели -h
как допустимый аргумент -d
опция, которая в практике означает это getopts
только бросит ошибку, если Ваша опция, которая требует аргумента, будет последней на командной строке, например:
test.sh
:
#!/bin/sh
while getopts ":xy:" o; do
case "${o}" in
:) echo "${OPTARG} requires an argument"; exit 1;
esac
done
Пример:
$ ./test.sh -y -x
$
$ ./test.sh -x -y
y requires an argument
Причина, почему Ваш второй подход не работает, состоит в том потому что парсинг это getopts
делает все еще то же, поэтому после того как Вы в цикле, "ущерб" уже нанесен.
Если Вы абсолютно хотите запретить это затем, как Benubird указал, необходимо будет проверить аргументы опции сами и бросить ошибку, если они равняются допустимой опции.
Я продолжил бы использовать getopts
но сделайте некоторую дополнительную проверку после: (непротестированный)
errs=0
declare -A option=(
[MYSQL_HOST]="-h"
[MYSQL_USER]="-u"
[MYSQL_PASS]="-p"
[BACKUP_DIR]="-d"
)
for var in "${!option[@]}"; do
if [[ -z "${!var}" ]]; then
echo "error: specify a value for $var with ${option[var]}"
((errs++))
fi
done
((errs > 0)) && exit 1
требует версии 4 удара
Необолочка Гну встроенный getopt действительно меньше работает на Вас, но позволяет большую гибкость, поскольку Вы добираетесь для определения то, что происходит после того, как флаг найден, включая откладывание аргументов сами.
Я нашел статью, выдерживающую сравнение getopts и getopt, который, вероятно, будет полезен, поскольку руководство довольно трудно понять (по крайней мере, перед кофе).
Во-первых, необходимо использовать if [ -z "$MYSQL_USER" ]
.
Во-вторых, нет никакой потребности в присвоении - if [ -z "$OPTARG" ]
будет хорошо работать.
В-третьих, я подозреваю то, что Вы на самом деле хотите, if [ ${#OPTARG} = 0 ]
. $ {#x} является возвратами вещи удара длина строкового $x (см. больше здесь).
В-четвертых, если бы Вы делаете свою собственную проверку, я рекомендовал бы getopt вместо getopts, поскольку это обеспечивает намного больше гибкости.
Наконец, для ответа на первый вопрос можно обнаружить, когда флаг передается как аргумент путем помещения списка флагов наверху, как это:
args=( -h -u -p -d )
И затем имея регистрацию опция, где Вы хотите проверить, является ли предоставленным аргументом опция, что-то вроде этого:
d)
BACKUP_DIR=$OPTARG
if [ "$(echo ${args[@]/$OPTARG/})" = "$(echo ${args[@]})" ]
then
echo "Argument is an option! Error!"
fi
Не идеальный ответ, но это работает! Ваша проблема состоит в том, что "-h" является совершенно допустимым аргументом, и Вы уступаете дорогу не, чтобы оболочка знала, что это только ищет параметры, которые не являются также допустимыми флагами.
while
цикл, работающий на основе опций. Это - метод, с которым я пошел как, хотя это является подробным по сравнению с другими, очень ясно, что продолжается в сценарии. И пригодность для обслуживания другими важна в этом случае. – batfastad 15.05.2013, 16:46