Как проверить, передан ли атрибут -h
в сценарий оболочки? Я хотел бы отображать справочное сообщение, когда пользователь звонит myscript.sh -h
.
Как я могу добавить метод справки к сценарию оболочки?
- Соответствующие примеры: stackoverflow.com/questions/14008125/ 22.10.2017
Ответы:
вот пример для bash:
usage="$(basename "$0") [-h] [-s n] -- program to calculate the answer to life, the universe and everything
where:
-h show this help text
-s set the seed value (default: 42)"
seed=42
while getopts ':hs:' option; do
case "$option" in
h) echo "$usage"
exit
;;
s) seed=$OPTARG
;;
:) printf "missing argument for -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
\?) printf "illegal option: -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
Чтобы использовать это внутри функции:
- используйте
"$FUNCNAME"
вместо$(basename "$0")
- добавьте
local OPTIND OPTARG
перед вызовомgetopts
Первый аргумент сценария оболочки доступен как переменная $1
, поэтому простейшей реализацией будет
if [ "$1" == "-h" ]; then
echo "Usage: `basename $0` [somestuff]"
exit 0
fi
Но что сказал анубхава.
[
является POSIX-совместимой версией. 20.03.2017 function
: следует заменить exit 0
на return
, если вы не хотите завершать работу оболочки после выполнения функции. (Я делал это раньше ????) 07.09.2017 вот часть, которую я использую для запуска сервера VNC
#!/bin/bash
start() {
echo "Starting vnc server with $resolution on Display $display"
#your execute command here mine is below
#vncserver :$display -geometry $resolution
}
stop() {
echo "Killing vncserver on display $display"
#vncserver -kill :$display
}
#########################
# The command line help #
#########################
display_help() {
echo "Usage: $0 [option...] {start|stop|restart}" >&2
echo
echo " -r, --resolution run with the given resolution WxH"
echo " -d, --display Set on which display to host on "
echo
# echo some stuff here for the -a or --add-options
exit 1
}
################################
# Check if parameters options #
# are given on the commandline #
################################
while :
do
case "$1" in
-r | --resolution)
if [ $# -ne 0 ]; then
resolution="$2" # You may want to check validity of $2
fi
shift 2
;;
-h | --help)
display_help # Call your function
exit 0
;;
-d | --display)
display="$2"
shift 2
;;
-a | --add-options)
# do something here call function
# and write it in your help function display_help()
shift 2
;;
--) # End of all options
shift
break
;;
-*)
echo "Error: Unknown option: $1" >&2
## or call function display_help
exit 1
;;
*) # No more options
break
;;
esac
done
######################
# Check if parameter #
# is set too execute #
######################
case "$1" in
start)
start # calling function start()
;;
stop)
stop # calling function stop()
;;
restart)
stop # calling function stop()
start # calling function start()
;;
*)
# echo "Usage: $0 {start|stop|restart}" >&2
display_help
exit 1
;;
esac
Немного странно, что я поместил старт-стоп-перезапуск в отдельный случай, но он должен работать
Для быстрого решения с одним вариантом используйте if
Если у вас есть только один вариант для проверки, и он всегда будет первым вариантом ($1
), то самым простым решением будет if
с тестом ([
). Например:
if [ "$1" == "-h" ] ; then
echo "Usage: `basename $0` [-h]"
exit 0
fi
Обратите внимание, что для совместимости с posix =
будет работать так же, как ==
.
Зачем цитировать $1
?
Причина, по которой $1
нужно заключить в кавычки, заключается в том, что если $1
нет, оболочка попытается запустить if [ == "-h" ]
и завершится ошибкой, потому что ==
был дан только один аргумент, когда он ожидал два:
$ [ == "-h" ]
bash: [: ==: unary operator expected
Для чего-то более сложного используйте getopt
или getopts
.
Как предложено от другие, если у вас есть несколько простых вариантов или вам нужна возможность принять аргумент, тогда вам обязательно следует пойти на дополнительную сложность использования getopts
.
В качестве краткого справочника мне нравится 60-секундное руководство по getopts.
Вы также можете рассмотреть программу getopt
вместо встроенной оболочки _ 18_. Он позволяет использовать длинные параметры и параметры после без аргументов (например, foo a b c --verbose
, а не просто foo -v a b c
). В этом ответе на Stackoverflow объясняется, как использовать GNU getopt
.
Джеффбирнес упомянул, что исходная ссылка умерла, но, к счастью, назад машина заархивировала его.
Лучше использовать средство getopt в bash. Пожалуйста, посмотрите эти вопросы и ответы для получения дополнительной помощи: Использование getopts в сценарии оболочки bash для получения длинных и коротких параметров командной строки
я думаю, вы можете использовать для этого случай ...
case $1 in
-h) echo $usage ;;
h) echo $usage ;;
help) echo $usage ;;
esac
Есть простой способ реализовать это без getopt
или getopts
:
display_help() {
# taken from https://stackoverflow.com/users/4307337/vincent-stans
echo "Usage: $0 [option...] {start|stop|restart}" >&2
echo
echo " -r, --resolution run with the given resolution WxH"
echo " -d, --display Set on which display to host on "
echo
# echo some stuff here for the -a or --add-options
exit 1
}
log() {
echo "This is a log"
}
while [[ "$#" -gt 0 ]]; do
case $1 in
-h|--help) display_help; shift ;;
-l|--log) log; shift ;;
# ... (same format for other required arguments)
*) echo "Unknown parameter passed: $1" ;;
esac
shift
done
basename
с начальным тире. 07.08.2013"$FUNCNAME"
, а не"$0"
. Также добавьтеlocal OPTIND OPTARG
07.08.2013FUNCNAME
работает. У меня все функции находятся в одном файле, так что это идеально подходит для расширения их во что-то полезное для других. 08.08.2013"$usage"
каждый, где его используете. 24.12.2016shift $((OPTIND - 1))
? 22.07.2019ls
и набралиls -l -a /
, тогда $ 1 будет/
22.07.2019