例如,如果我有脚本 ./foo 需要 10 个参数,而我只想传递第 8 个参数。目前我知道如何做到这一点的唯一方法是:
./foo '' '' '' '' '' '' '' 'bar'
有更简单/更好的方法吗?
答案1
假设您可以更改脚本,您应该考虑使用可选参数(选项)而不是必需参数(参数)。
如果您将前 7 个参数中的每一个作为选项,并将它们默认为空字符串,那么您可以这样做:
./foo bar
如果您使用POSIX 兼容外壳你可以使用getopts
实用程序,或程序getopt
。bash
- 像大多数 shell 一样 -getopts
作为内置提供。无论哪种方式都比滚动您自己的命令行解析器更容易。
除非您实现类似最后一个 X 非选项参数是最后一个 Y 参数和 XY 选项参数的值,否则如果您想设置其中任何一个,则必须在 7 个(现在为空)字符串中的每个字符串之前提供选项字符串。然而,这不是常见的做法,通常选项始终是选项,参数始终是参数,并且选项“插入”的顺序是自由的。
答案2
执行此操作的另一种方法是命名要声明的参数,然后执行以下操作:
{ cat >./foo
chmod +x ./foo
eight=declared ./foo
eight=declared_and_preferred \
./foo 1 2 3 4 5 6 7 8
./foo 1 2 3 4 5 6 7 8
./foo
} <<\SCRIPT
#!/usr/bin/sh
: ${eight:=${8:-some_default}}
printf '$eight = %s\n' "$eight"
#END
SCRIPT
输出
$eight = declared
$eight = declared_and_preferred
$eight = 8
$eight = some_default
在上面的示例中,显式声明的环境变量优于命令行参数,但当环境变量为空或未设置时,将使用命令行参数。当双方都处于第 8 位置时和环境变量$eight
为空或未设置默认值一些默认值被分配给$eight
.在任何一种情况下,如果空应该是可接受的值,则可以从or语句:
中删除。:-
:=
该变量$eight
也可以设置为:
printf '$eight = %s\n' "${eight:=${8:-some_default}}"
...前一行完全省略,但我想证明以这种方式声明变量确实会产生持久值,所以我用两个命令完成了它。无论哪种方式$eight
都设置为该复合参数扩展的最终值。
getopts
- 对于健壮的脚本 - 通常是处理命令的最佳方式选项。另一方面,位置参数几乎总是鲁棒处理的最简单方法操作数在脚本中。
例如:
touch file$(seq -ws\ file 100)
./foo *
输出
$eight = file008
在那里我们只看到了第八个操作数,但从我的测试目录中找到了其中的 101 个操作数。