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

问题描述 投票:0回答:8

如何检查

-h
属性是否已传递到 shell 脚本中? 我想在用户调用
myscript.sh -h
时显示帮助消息。

unix shell
8个回答
213
投票

这是 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

例如,一个将两个数字相加的函数,或者如果给出

-s
选项,则减去两个数字:

add () {
    local OPTIND OPTARG opt operator="+"
    while getopts :hs opt; do
        case $opt in
            s)  operator="-" ;;
            h)  echo "a function to add or subtract two numbers";
                return 1 ;;
            \?) echo "unknown option: -$OPTARG" 1>&2;
                return 2 ;;
        esac
    done
    shift $((OPTIND - 1))
    echo "$(( $1 $operator $2 ))"
}
$ add 15 4
19
$ add -s 15 4
11
$ add -h; echo $?
a function to add two numbers
1
$ add -x; echo $?
unknown option: -x
2

62
投票

shell 脚本的第一个参数可用作变量

$1
,因此最简单的实现是

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

但是阿努巴瓦所说的。


39
投票

这是我用它来启动 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

我将开始停止重新启动放在单独的情况下有点奇怪,但它应该可以工作


27
投票

要获得快速的单选项解决方案,请使用
if

如果您只有一个选项需要检查,并且它始终是第一个选项 (

$1
),那么最简单的解决方案是
if
和测试 (
[
)。例如:

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

请注意,对于 posix 兼容性,

=
将与
==
一样工作。

为什么引用
$1

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

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

对于任何更复杂的事情,请使用
getopt
getopts

正如建议by其他,如果您有多个简单选项,或者需要您的选项接受参数,那么您绝对应该选择使用

getopts
的额外复杂性。

作为快速参考,我喜欢 60 秒 getopts 教程

您可能还想考虑使用

getopt
程序而不是内置 shell
getopts
。它允许使用长选项和选项after非选项参数(例如
foo a b c --verbose
而不仅仅是
foo -v a b c
)。 这个 Stackoverflow 答案解释了如何使用 GNU
getopt

jeffbyrnes提到原始链接已失效,但值得庆幸的是回程机器已将其存档。


8
投票

有一种简单的方法可以实现此目的,无需

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

5
投票

最好使用 bash 的 getopt 工具。请查看此问答以获得更多帮助:在 bash shell 脚本中使用 getopts 获取长和短命令行选项


2
投票

这是一种超级紧凑但可读的方法,可以根据 @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.

$ _

0
投票

我认为你可以为此使用案例...

case $1 in 
 -h) echo $usage ;; 
  h) echo $usage ;;
help) echo $usage ;;
esac
© www.soinside.com 2019 - 2024. All rights reserved.