如何向 shell 脚本添加帮助方法?

如何检查 -h属性是否已经传递到 shell 脚本中?当用户调用 myscript.sh -h时,我想显示一个帮助消息。

186389 次浏览

最好使用 bash 的 getopt 功能

Shell 脚本的第一个参数可以作为变量 $1使用,因此最简单的实现是

if [ "$1" == "-h" ]; then
echo "Usage: `basename $0` [somestuff]"
exit 0
fi

但是阿努巴娃说。

下面是 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")
  • 在调用 getopts之前添加 local OPTIND OPTARG

对于快速的单选项解决方案,使用 if

如果您只有一个选项要检查,并且它总是第一个选项($1) ,那么最简单的解决方案是带有测试的 if([)。例如:

if [ "$1" == "-h" ] ; then
echo "Usage: `basename $0` [-h]"
exit 0
fi

注意,对于 posx 兼容性,=将与 ==一样工作。

为什么引用 $1

$1需要用引号括起来的原因是,如果没有 $1,那么 shell 将尝试运行 if [ == "-h" ]并失败,因为 ==只有一个参数,而它期望有两个参数:

$ [ == "-h" ]
bash: [: ==: unary operator expected

对于任何更复杂的使用 getoptgetopts

作为 建议 作者 其他人,如果您有一个以上的简单选项,或者需要您的选项来接受一个参数,那么您一定要使用 getopts的额外复杂性。

作为一个快速的参考,我喜欢 60秒 getopts 教程.

您可能还需要考虑使用 getopt程序而不是内置的 shell getopts。它允许使用长选项和选项 之后非选项参数(例如,foo a b c --verbose而不仅仅是 foo -v a b c)。这个 Stackoverflow 答案解释了如何使用 GNUgetopt

? Jeffbyrnes提到,原始链接死亡,但幸运的是,很久以前的机器已将其存档。

我觉得你可以用这个案子。

case $1 in
-h) echo $usage ;;
h) echo $usage ;;
help) echo $usage ;;
esac

下面是我用它启动 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

这是一个有点奇怪,我把启动停止重新启动在一个单独的情况下,但它应该工作

有一个不需要 getoptgetopts就能实现的简单方法:

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

这里有一个超级紧凑,但可读的方式来添加基于@zeb 的版本的基本帮助。它同时处理常用的 -h--help标志。

[ "$1" = "-h" -o "$1" = "--help" ] && echo "
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.


Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
" && exit

结果是这样的:

$ ./myscript.sh -h


Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.


Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.


$ _