在一次指令中位置数是一个特殊参数时,如何使用位置参数?

时间:2019-01-14 17:58:57

标签: bash

我想打开bash并获取最后一个位置参数。 所以我尝试了这个:

bash -cv 'echo $$#' -- 1 2 'The Third'

我的想法是使用$#来了解参数的数量。 因为这里有3个参数-1、2和'The Third',所以$#应该是3,而$$#应该变成$3并向我返回'The Third'。

但是事实证明,$$是第一个被评估的值,其值为shell进程ID。

我搜索了一段时间后得到了解决方案:

bash -cv 'eval echo \${$#}' -- 1 2 'The Third'

它可以工作,但是感觉就像我将一个命令分成了两个。 首先进行扩展,然后进行评估。

有可能一次执行命令吗? 像

bash -cv 'echo $($#)' -- 1 2 'The Third'

设置扩展之间的优先级。

2 个答案:

答案 0 :(得分:4)

您的想法还可以,但是那不是用bash语法编写它的方式。使用带有感叹号引入的“间接扩展”:

bash -cv 'echo ${!#}' -- 1 2 'The Third'
# => The Third

来自man bash

  

${parameter}

     

参数的值被替换。当parameter是一个多位数字的位置参数时,或者当parameter后跟一个不被解释为其名称一部分的字符时,必须使用大括号。

     

如果参数的第一个字符是感叹号,则会引入变量间接访问级别。 Bash使用由其余参数形成的变量的值作为变量的名称;然后扩展此变量,并在其余替换中使用该值,而不是参数本身的值。这称为间接扩展。例外情况是下面描述的${!prefix*}${!name[@]}的扩展。感叹号必须紧随左括号之后才能引入间接作用。

答案 1 :(得分:2)

您可以在bash

中执行此操作
bash -cv 'echo "${@: -1}"' -- 1 2 'The Third'

echo "${@: -1}"
The Third

或者您可以使用数组先存储所有参数:

bash -cv 'arr=("$@"); echo "${arr[@]: -1}"' -- 1 2 'The Third'

arr=("$@"); echo "${arr[@]: -1}"
The Third