使用 -option 和参数调用 shell 脚本

使用 -option 和参数调用 shell 脚本

我需要test.sh按以下方式调用 shell 脚本:

./test.sh -run/-rerun  username password

如何检查它们是否已通过-run-rerun在我的 shell 脚本中选项?

答案1

一个常见的方法是使用getopt用于分解传递给脚本的命令行选项以便于解析的实用程序。getopt支持带或不带参数的短(单字符)和长(多字符)选项。getopt调用时会传递两种参数:修改getopt将解析选项的方式的选项,以及要解析的调用脚本的参数。

指定如何解析剩余参数的最重要选项getopt如下:

  • -o, --options shortopts要解析的短选项。该选项的参数shortopts是一个字符串,应被识别为短选项。带有必需参数的选项字符后应跟一个冒号:,而带有可选参数的选项后应跟两个冒号::。例如,该shortopts字符串ab:c::对应于以下识别的选项-a-b arg-c-c arg请注意,如果未指定此选项,则会将第一个不以(并且不是选项参数)getopt开头的选项视为字符串。-shortopts

  • -l, --longoptions longopts要解析的长选项。可以一次指定多个选项,用逗号分隔选项名称,或者-l可以多次给出该选项。必需和可选参数通过选项名称后带有或的-o选项来指示。:::

  • -a, --alternative一个共同的约定,尤其是GNU软件的一个缺点是长选项前面有两个破折号,例如--run。该-a选项指示getopt允许长选项以单个-字符开头。

  • -q,--quiet如果getopt在要解析的参数中遇到无法识别的选项或缺少必需的参数,它将打印一条getopt: unrecognized option '[option name]'getopt: option '[option name'] requires an argumentto形式的消息stderr,生成正常输出 tostdout并以非零状态退出。该-q选项可用于抑制错误消息。

  • -n, --name progname该选项可用于指定getopt报告上述错误时将使用的程序名称。

第一个非选项参数(不是选项参数或shortopts如上所述被视为字符串)被视为getopt要解析的参数列表的开始。这些参数的开始也可以用 指示--,在这种情况下,后面的第一个参数--被视为要解析的参数列表的开始。

of 的正常输出getopt是已识别选项的扩展列表,如下所示:

  • 一起给出的短选项,例如-abc,被扩展为单独的选项,即-a -b -c

  • 如果-a指定为 的选项getopt,则以单个破折号开头的长选项(例如-foo)会以附加破折号作为前缀,即--foo

  • 选项的必需参数和可选参数被引用,例如,-b argbecomes和become 。-b 'arg'--foo arg--foo=arg--foo 'arg'

  • 任何剩余的参数都被引用并与选项分隔开--

扩展的优点是更容易解析分解的选项,因为需要考虑的情况较少。getopt下面给出了使用问题中指定的命令行选项解析的示例:

#!/bin/bash

OPTS=`getopt -a -l run -l rerun -- "$0" "$@"`
if [ $? != 0 ] # There was an error parsing the options
then
  exit 1 
fi

eval set -- "$OPTS"

while true; do
  case "$1" in
    --run) echo "option --run specified"; shift;;
    --rerun) echo "option --rerun specified"; shift;;
    --) shift; break;;
  esac
done

echo "Args:" 
for arg # Process remaining arguments
do
  echo $arg
done

解释:

OPTS=`getopt -a -l run -l rerun -- "$0" "$@"`

这里我们设置OPTS变量来保存调用的输出getopt。在本例中,传递到此处的参数getopt是 shell 设置的内置变量。bash保存$0脚本的名称并$@保存传递给脚本的所有命令行参数(单独引用)。getopt将根据指定的选项处理参数。在此示例中,将识别不带参数的getopt长选项--run--rerun由于该-a选项getopt还将识别表格-run-rerun。调用的结果getopt是扩展的参数列表。例如,诸如 之类的脚本调用test.sh -run username password会被 shell 扩展为getopt调用getopt -a -l run -l rerun -- "test.sh" "-run" "username" "password"getopt依次输出扩展后的参数--run -- 'username' 'password'


if [ $? != 0 ] # There was an error parsing the options
then
  exit 1 
fi

内置变量$?保存最近执行的命令的返回值。非零返回值表示getopt遇到错误。


eval set -- "$OPTS"

这实际上将用 . 输出的扩展参数替换传递给脚本的原始命令行参数getopt


while true; do
  case "$1" in
    --run) echo "option --run specified"; shift;;
    --rerun) echo "option --rerun specified"; shift;;
    --) shift; break;;
  esac
done

$1循环将从第一个位置参数开始依次处理每个位置参数。扩展后getopt,只需考虑三种情况。在处理结束时,每种情况shift都会改变位置参数,使得$2变为$1$3变为$2等等。因此,位置参数$1将在循环的每次迭代中保存一个新值。

如果正在处理的选项需要一个必需的参数,则可以case通过位置参数在语句中访问该参数值$2。当选项及其参数被处理后,位置参数需要移动 2 才能摆脱这两个选项的论点。

当在已识别选项之后、剩余参数之前getopt输出 a 时, case 表示选项列表的结尾和循环的终止条件。----while


echo "Args:" 
for arg # Process remaining arguments
do
  echo $arg
done

for arg是 的缩写for arg in "$@"。请注意,在while循环之后,由于shift每种情况,现在仅保存输出中$@后面的剩余参数。--getopt

相关内容