【问题标题】:Add usage content in shell script without getopts在没有 getopts 的 shell 脚本中添加使用内容
【发布时间】:2013-02-20 08:11:48
【问题描述】:

我有脚本,我需要在其中显示使用命令,以防用户在执行脚本时错过任何强制性信息。

Usage : Script -s <server> -i <instance> -u <user> -p <password> <query> -w <warning value> -c <critical value>

附上所有OPTIONS的解释

我从以下变量时尚的参数中获取值。但我希望这种用法与 shell 脚本中的验证一起使用。

SERVER=$1
INSTANCE=$2
USER=$3
DB_PASSWD=$4
QUERY=$5
VAL_WARN=$6
VAL_CRIT=$7

我曾尝试使用getopts,但未能使用,因为&lt;query&gt; 在传递值之前没有-q 参数。

我已经尝试寻找所有其他方法,但每个人都建议 getopts 这对我来说不是可行的解决方案。

请帮帮我..

【问题讨论】:

  • 选项字母的优点之一是它允许用户以任何顺序放置项目。如果订单是固定的,则无需操心-s等选项;这只会使用户输入额外的内容,基本上没有任何好处。我注意到原始命令行中的服务器字符串是$2(不是$1)。你不能规范你的命令,以便需要-q,或者查询是最后一个参数吗?是否有任何选项具有合理的默认值?如果是这样,请使用它们而不是要求用户输入 13 个参数。您的用户会感谢您,您的脚本会更容易编写。

标签: linux shell unix getopts


【解决方案1】:

使用 shift 遍历所有参数,例如:

#!/bin/sh

usage ()
{
  echo 'Usage : Script -s <server> -i <instance> -u <user> -p <password>'
  echo '                  <query> -w <warning value> -c <critical value>'
  exit
}

if [ "$#" -ne 13 ]
then
  usage
fi

while [ "$1" != "" ]; do
case $1 in
        -s )           shift
                       SERVER=$1
                       ;;
        -i )           shift
                       INSTANCE=$1
                       ;;
        -u )           shift
                       USER=$1
                       ;;
        -p )           shift
                       PASSWORD=$1
                       ;;
        -w )           shift
                       WARNINGVAL=$1
                       ;;
        -c )           shift
                       CRITICVAL=$1
                       ;;
        * )            QUERY=$1
    esac
    shift
done

# extra validation suggested by @technosaurus
if [ "$SERVER" = "" ]
then
    usage
fi
if [ "$INSTANCE" = "" ]
then
    usage
fi
if [ "$USER" = "" ]
then
    usage
fi
if [ "$PASSWORD" = "" ]
then
    usage
fi
if [ "$QUERY" = "" ]
then
    usage
fi
if [ "$WARNINGVAL" = "" ]
then
    usage
fi
if [ "$CRITICVAL" = "" ]
then
    usage
fi

echo "ALL IS WELL. SERVER=$SERVER,INSTANCE=$INSTANCE,USER=$USER,PASSWORD=$PASSWORD,QUERY=$QUERY,WARNING=$WARNINGVAL,CRITIC=$CRITICVAL"

应该做的伎俩。

编辑:按照@technosaurus 的建议在脚本中添加了参数验证

【讨论】:

  • 只需要最后检查 [ ! "$PASSWORD" ] &amp;&amp; usage #and 类似的其他强制参数
  • @technosaurus AFAICS 检查已经存在:while [ "$1" != "" ] ...
  • 这仍然可以工作 Script q q q q q q q q q q q q q 并且不会设置任何必需的值
  • @technosaurus 在你的两个 cmets 上都是正确的。我已经相应地更新了脚本(我误读了原始问题,一开始只考虑解析。):)
  • @matt.nguyen 我没有测试,但不应该是 == 或 -eq 吗? (我忘记了哪个字符串/数字)...但是要测试是否设置了变量,我通常只做[ "$VAR" ] || usage ...如果变量是可选的但需要设置为 something您可以使用 ${VAR:-default value} ...我的猜测是 可能其中一些
【解决方案2】:

getopts 正在为good reason 发愁。您应该更改脚本的界面以符合人们的期望。

或者,您可以使用getopts 两次,首先用于query 之前的选项,shift,然后用于其余选项。

【讨论】:

    【解决方案3】:

    试试这个

    usage()
    {
       echo "$0 -s <server> -i <instance> -u <user> -p <password> <query> -w <warning value> -c <critical value>"
    }
    
    for i in {0..12}
    do
        arg=`expr $i +1`
        test ! "${!arg}" && usage && break
    done
    

    希望对你有帮助

    【讨论】:

    • 或者你可以for i in {1..13} 去掉子shell。
    【解决方案4】:

    嗯,一个非常像穴居人的方式应该是这样的

    usage ()
    {
      echo 'Usage : Script -s <server> -i <instance> -u <user> -p <password>'
      echo '                  <query> -w <warning value> -c <critical value>'
      exit
    }
    
    [ ${13} ] || usage
    

    【讨论】:

    • 谢谢.. 现在如果用户在执行时不提供 13 个参数,我会知道。但此外,我确实收到了一个丑陋的错误消息,例如“第 76 行:[:21:预期的一元运算符”,因为这些是强制性的.. 我怎样才能摆脱这个??
    【解决方案5】:

    这是一种非标准方法,但我发现它非常有用。无需将值作为参数传递给特定标志(这很烦人;不应该要求用户指定每个值,但应该提供合理的默认值),您可以简单地通过环境直接传递它们,这样典型的调用看起来喜欢:

    SERVER=blah INSTANCE=foo Script 
    

    如果你使用小写的变量名,这样用户就不必大喊大叫了。这允许脚本完全避免解析命令行,因为变量的值将在脚本开始时设置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2021-11-22
      • 2017-11-17
      • 2021-05-24
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多