我有bash脚本,我希望能够根据调用脚本时传递的选项跳过(即不执行)它的一些命令。
为了说明我想要实现的目标,我编写了一个包含if
语句的脚本,这些语句基本上实现了相同的目标。
if [ "$1" != "skipA" ]
then
echo "A"
fi
if [ "$1" != "skipB" ]
then
echo "B"
fi
if [ "$1" != "skipC" ]
then
echo "C"
fi
if [ "$1" != "skipD" ]
then
echo "D"
fi
当调用脚本时未传递任何参数时,将执行所有四条echo
语句。如果我想跳过其中一个echo语句,我使用skipLETTER
作为第一个参数:
./script.sh skipA
并且打印除了CCD_ 4之外的所有字母。它是有效的,但它确实有很多限制——首先,我不能使用相同的参数($1
)跳过许多部分。我想用选项实现同样的事情,所以我可以键入类似的内容:
./script -skipA -skipD
结果只打印CCD_ 6和CCD_。
我知道我可以使用getopt
或getopts
来实现这一点,但我找不到任何简单的使用示例来实现我所描述的。
我使用具有以下算法的代码:
- 捕获file1中函数中的所有可执行代码
- 根据文件2中的逻辑调用序列中的每个函数
- 在调用file2时,每次调用都将被限制为一行,并将其命名为步骤
- 使用跳过选项调用file2
- 使用if语句将行读取为步骤,并检查当前步骤是否小于所需步骤,如果是,则继续下一步。否则使用eval对其执行操作
POSIX标准的getopts不能做长选项,只能做单字符选项,因此您不能将其用于问题中列出的确切接口。
顺便说一句,长选项应该用两个破折号引入,而不是一个,否则在不了解实用程序细节的情况下,无法判断-skipA是一个单独的选项(可能带有optarg),还是捆绑了五个单字符选项(-x -y
与-xy
相同,两者都不同于--xy
)。
继续使用可移植代码(getopts规范),并为skip选项选择s
,下面是一个简短的示例:
#!/bin/sh
contains()
{
case "$1" in
*$2*) return 0 ;;
esac
return 1
}
requested()
{
! contains "$skip" "$1"
}
while getopts s: optname; do
case $optname in
s) skip="$OPTARG" ;;
?) exit 1 ;;
esac
done
if requested A; then
echo A
fi
if requested B; then
echo B
fi
if requested C; then
echo C
fi
if requested D; then
echo D
fi
您可以使用CCD_ 14和类似产品进行测试。它将对未知选项和-s
做出反应,而不使用类似的optarg消息
./skip-parts.sh: illegal option -- x
./skip-parts.sh: option requires an argument -- s
如果您不喜欢默认的错误消息,您可以通过在getopts(1)的第一个参数前面加一个冒号来使它们静音,并在?
的情况下给出自己的错误消息(选项需要一个参数情况通过将optname