${@:-1} 真的返回最后一个参数吗?

Pie*_*tru 3 bash arguments

当我有两个参数时,我正在运行以下代码

if (( $# == 2 )); then
  : ${fdir:="${@:-1}"}
  pfm -w2 "" "unspecified -d option"
  echo "use last argument as substitute"
  printf '%s\n\n' "fdir: ${@:-1}"
  echo "\$1: $1  \$2: $2"
Run Code Online (Sandbox Code Playgroud)

这是结果

pregion --dyn "John" ./01cuneus
pregion --dyn John ./01cuneus

unspecified -d option
use last argument as substitute
fdir: John

./01cuneus

$1: John  $2: ./01cuneus
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 6

不,"${@:-1}"不会。但"${@: -1}"确实如此。

但是要注意,至少在 Bash 和 Ksh 中,如果没有位置参数,则"${@: -1}"给出"$0",即 shell 名称。这类似于如何使用${@:0}给出$0和所有位置的位置参数。岩组似乎并没有给$0${@: -1}或清洁剂${@[-1]}

这里的小问题,就是${var:-value}一个标准的扩展,其扩展为默认值的值,如果VAR没有设置或者为空。子串/阵列片扩张${var:p:n},其中${@: -1}是一种特殊情况,是不标准和壳解释${@:-1}为对默认值扩展$@。空格消除了歧义,因此将索引放在变量中,例如i=-1; echo "${@:i}"

set -- a b c        
echo "${@: -1}"       # prints 'c', the last element
echo "${@:-1}"        # prints 'a b c'

set -- 
echo "${@: -1}"       # prints '/bin/bash' or something like that
echo "${@:-1}"        # prints '1', the default value given
echo "${@:-no args}"  # prints 'no args'
Run Code Online (Sandbox Code Playgroud)

同样如注释中所述,in 中的扩展: ${fdir:="${@:-1}"}未加引号,因此可能会导致 shell 生成任意长的文件名列表。这可以通过: "${fdir:="${@: -1}"}",或者可能更具可读性的方式来防止[ -z "$fdir"] && fdir="${@: -1}"