Dav*_*vid 10 bash shell-script echo
我正在编写一个 shell 脚本,我需要打印脚本的第 n 个参数。
例如,假设我们有n=3
并且我们的脚本使用足够的参数运行。现在我需要打印第n
th 个参数,即$3
。
但如果n=2
,我们会打印参数$2
。
我不想使用if
语句。我想做类似的事情
echo $($n)
Run Code Online (Sandbox Code Playgroud)
但上面的方法并没有按照我需要的方式工作。
Sté*_*las 26
按时间顺序,在各种 shell 中:
$argv[$n]
自 1991 年以来也适用于 zsh,自 2005 年以来也适用于 Fish)$argv[n]
// $@[n]
($*[n]
最后一个也被 yash 支持,但只有额外的大括号:${@[n]}
/${*[n]}
)$$n
/$*($n)
(也适用于 es、akanga)${@:n:1}
, ${*:n:1}
(自 1996 年起也受 bash 支持;自 2010 年起zsh 也受支持,尽管您需要${@:$n:1}
或${@: n:1}
避免与 csh 样式修饰符发生冲突,并查看那里有关"$*"
情况)${!n}
${(P)n}
:.请记住,在 ksh93/bash/yash 中,您至少需要在列表上下文中引用参数扩展,而 csh 很难用来编写可靠的代码。
在 中,当第 n个时,列表上下文中和bash
之间存在差异"${!n}"
"${@:n:1}"
,因为后者扩展为根本没有参数,而前者扩展为一个空元素。
在类似 Bourne 的 shell 中(但不是 Bourne shell,因为它不适用于第 9 个以上的索引),并且使用标准 POSIX sh 语法,您还可以执行以下操作:
eval "nth=\${$n}"
Run Code Online (Sandbox Code Playgroud)
$n
如果不包含严格大于 0 的整数的规范十进制表示,那么所有这些之间的行为也会有所不同。如果您不能保证会出现这种情况,那么使用其中的大多数(而不仅仅是eval
一个)会引入任意命令执行漏洞(唯一的例外是 withrc
和 可能是csh
上面的)。
另请记住,除了zsh
(with echo -E - $argv[n]
)、yash
(with ECHO_STYLE=raw echo "${*[$n]}"
) 和fish
(with echo -- $argv[$n]
) 之外,echo
不能用于输出任意数据,请printf '%s\n' ...
改用)。
ter*_*don 17
您传递给脚本的参数存储在数组中@
,因此执行您想要的操作的简单方法是获取一个数组 slice,从位置开始n
,长度为 1:
#!/bin/bash
n=3
echo "Argument $n: ${@:n:1}"
Run Code Online (Sandbox Code Playgroud)
如果您使用一些参数运行此命令,您将得到:
$ foo.sh a b c d e f
Argument 3: c
Run Code Online (Sandbox Code Playgroud)
另一种选择,也就是您最初要求的,称为“间接扩展”:
#!/bin/bash
n=3
echo "Argument $n: ${!n}"
Run Code Online (Sandbox Code Playgroud)
运行这个:
$ foo.sh a b c d e f
Argument 3: c
Run Code Online (Sandbox Code Playgroud)
简单的便携式 shell(无 bash 依赖性)解决方案(对命令的潜在缺陷取模echo
;它可以替换为printf
):
print_nth () {
shift "$1"
echo "$1"
}
Run Code Online (Sandbox Code Playgroud)
然后做:
print_nth "$n" "$@"
Run Code Online (Sandbox Code Playgroud)