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

ttt*_*ppp 117 unix shell

如何检查-h属性是否已传递到shell脚本?我想在用户呼叫时显示帮助消息myscript.sh -h.

gle*_*man 155

这是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))
Run Code Online (Sandbox Code Playgroud)

  • imside a function使用`"$ FUNCNAME"`不是"$ 0"`.另外,添加`local OPTIND OPTARG` (5认同)
  • @sigur,请确保在每个使用它的地方引用"$ usage"`**. (5认同)
  • `shift $((OPTIND - 1))` 是做什么用的? (2认同)
  • 这将从位置参数中删除所有选项,以便 $1 将成为选项后面的第一个参数。如果您正在为“ls”编写函数,并且输入“ls -l -a /”,则 $1 将是“/” (2认同)

seb*_*seb 43

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

if [ "$1" == "-h" ]; then
  echo "Usage: `basename $0` [somestuff]"
  exit 0
fi
Run Code Online (Sandbox Code Playgroud)

但阿努巴瓦说的是什么.

  • 是的,虽然OP没有指定bash,而`[`是符合POSIX的版本. (2认同)
  • **注意 - 对于在 `function` 内部使用:** 如果您不想在运行函数后终止 shell,则应该将 `exit 0` 替换为 `return`。(我以前做过) (2认同)

小智 26

这是我用它来启动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
Run Code Online (Sandbox Code Playgroud)

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


Mar*_*oth 14

如果您只有一个选项可以检查,它将始终是第一个选项($1),那么最简单的选项是if带有test([).例如:

if [ "$1" == "-h" ] ; then
    echo "Usage: `basename $0` [-h]"
    exit 0
fi
Run Code Online (Sandbox Code Playgroud)

请注意,对于posix兼容性=将起作用==.

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

$ [ == "-h" ]
bash: [: ==: unary operator expected
Run Code Online (Sandbox Code Playgroud)

正如其他人建议的 那样 ,如果你有多个简单的选项,或者需要你的选择来接受参数,那么你肯定应该考虑使用的额外复杂性.作为快速参考,我喜欢60秒的getopts教程.getopts

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

jeffbyrnes提到原来的链接已经死了,但幸运的是后机已经归档了.

  • 遗憾的是,60 秒 getopts 教程的链接已失效;bashcurscancer.com 似乎已经不复存在了。这是 [Wayback Machine 版本](https://web.archive.org/web/20120409221849/http://bashcurescancer.com/the-60-second-getopts-tutorial.html) 的链接。 (3认同)

Ege*_*urk 8

有一种简单的方法可以在不使用getoptor 的情况下实现此目的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
Run Code Online (Sandbox Code Playgroud)


anu*_*ava 5

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