2011-03-29 121 views
70

如何检查-h属性是否已传递到shell脚本中?我想在用户拨打myscript.sh -h时显示帮助信息。如何将帮助方法添加到shell脚本中?

+0

相关例子:https://stackoverflow.com/questions/14008125/shell-script-common-template – 2017-10-22 09:27:36

回答

92

这里是对于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)) 
+0

我试图在一个函数内部,但是当我尝试运行该函数时,我得到这个错误“basename:invalid option - 'b'”。 看起来它试图将“-bash”传递给带有前导破折号的“basename”。 – 2013-08-07 15:40:53

+2

不使用'“$ FUNCNAME”'而不是'“$ 0”'。另外,添加'本地OPTIND OPTARG' – 2013-08-07 16:08:00

+0

谢谢。 'FUNCNAME'起作用。我将所有函数都放在一个文件中,所以这对于将它们扩展为对其他文件有用的东西来说是完美的。 – 2013-08-07 22:36:11

25

的第一个参数一个shell脚本可以作为变量$1,所以最简单的实现将是

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

但说了什么anubhava。

+0

感谢@MarkBooth,错字校正(加上引号包装改进) – seb 2013-03-07 20:11:49

+0

你应该做的习惯将if包含在[[...]]中以包含条件,以避免对变量进行错误解析:https://github.com/bahamas10/bash-style-guide#bashisms – JREAM 2017-03-19 15:38:53

+1

是的,虽然OP没有指定bash,'['是POSIX兼容版本。 – seb 2017-03-20 16:16:41

9

如果你只有一个选项,以检查它永远是第一个选项($1),那么最简单的方法是if与测试([) 。例如:

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

注意,对于POSIX兼容=将工作以及==

原因需要$1被引号括起来的是,如果没有$1那么shell将尝试运行if [ == "-h" ]和失败,因为==只被给予当它被期待两个单独的参数:

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

作为suggestedbyothers,如果你有多个简单的选项,或者需要你的选项来接受参数,那么你一定要去使用getopts的额外复杂性。作为快速参考,我喜欢The 60 second getopts tutorial†

您可能还想考虑getopt程序,而不是内置的shell getopts。它允许在非选项参数(例如foo a b c -v而不仅仅是foo -v a b c)之后使用长选项和选项This Stackoverflow answer说明如何使用GNU getopt

† jeffbyrnes提到original link已经死亡,但幸好0123Å已将其归档。

+0

谢谢!现在我一直很开心地使用getopts,但我也会看看getopt。 – tttppp 2013-03-01 11:57:21

+1

不幸的是,连接到60秒的getopts教程是死的;看来bashcurescancer.com不在了。以下是[Wayback Machine版本]的链接(https://web.archive.org/web/20120409221849/http://bashcurescancer.com/the-60-second-getopts-tutorial.html)。 – jeffbyrnes 2014-03-12 19:33:52

-1

我认为你可以使用情况下这...

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

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

这是一个有点怪异,我放在一个部分在一个单独的情况下启动停止重启,但它应该工作

+0

如果你给一个空的选项-d;会不会无限循环? – zerobane 2016-01-17 09:03:11

-1

我只需上传在线手册文件,并用curl检索它。例如,下面的代码是从Github获取的。

####################################### 
    # Show help 
    # 
    # Globals: 
    # None 
    # Arguments: 
    # None 
    # Returns: 
    # None 
    # 
    ####################################### 
    show_help() { 
     curl https://raw.githubusercontent.com/KENJU/shellscript_todo/master/MANUAL | less 
    }