当 n 直到运行时才知道时,如何打印脚本的第 n 个参数?

当 n 直到运行时才知道时,如何打印脚本的第 n 个参数?

我正在编写一个 shell 脚本,我需要打印脚本的第 n 个参数。

例如,假设我们有n=3并且我们的脚本使用足够的参数运行。现在我需要打印第nth 个参数,即$3

但如果n=2,我们会打印参数$2

我不想使用if语句。我想做类似的事情

echo $($n)

但上面的方法并没有按照我需要的方式工作。

答案1

按时间顺序,在各种 shell 中:

  • csh(70 年代末):($argv[$n]自 1991 年以来也适用于 zsh,自 2005 年以来也适用于 Fish)
  • zsh (1991): $argv[n]// (最后一个也被 yash 支持,但只有额外的大括号$@[n]: / )$*[n]${@[n]}${*[n]}
  • rc (90 年代初): $$n/ $*($n)(也适用于 es、akanga)
  • ksh93 (1993): ${@:n:1}, ${*:n:1}(自 1996 年以来 bash 也支持;zsh 也自2010年以来,尽管您需要${@:$n:1}${@: n:1}避免与 csh 样式修饰符发生冲突并查看那里关于"$*"案件)
  • 巴什(1996):${!n}
  • 兹什(1999年): ${(P)n}.

请记住,在 ksh93/bash/yash 中,您至少需要在列表上下文中引用参数扩展,而 csh 很难用来编写可靠的代码。

在 中,当第 n位置参数未设置时,列表上下文中和bash之间存在差异,因为后者扩展为根本没有参数,而前者扩展为一个空元素。"${!n}""${@:n:1}"

在类似 Bourne 的 shell 中(但不是 Bourne shell,因为它不适用于第 9 个以上的索引),并且使用标准 POSIX sh 语法,您还可以执行以下操作:

eval "nth=\${$n}"

如果不包含严格大于 0 的整数的规范十进制表示,那么所有这些之间的行为也会有所不同。$n如果您不能保证会出现这种情况,那么使用其中的大多数(而不仅仅是一个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' ...改为使用)。

答案2

您传递给脚本的参数存储在数组中@,因此执行您想要的操作的简单方法是采用数组切片,从位置开始n,长度为 1:

#!/bin/bash

n=3
echo "Argument $n: ${@:n:1}"

如果您使用一些参数运行此命令,您将得到:

$ foo.sh a b c d e f
Argument 3: c

另一种选择,也就是您最初要求的,称为“间接扩展”:

#!/bin/bash

n=3
echo "Argument $n: ${!n}"

运行这个:

$ foo.sh a b c d e f
Argument 3: c

答案3

您可以使用变量间接:

#!/bin/bash
n=3
echo "${!n}"

答案4

简单的便携式 shell(无 bash 依赖性)解决方案(对命令的潜在缺陷取模echo;它可以替换为printf):

print_nth () {
    shift "$1"
    echo "$1"
}

然后做:

print_nth "$n" "$@"

相关内容