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

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

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

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"

这是结果

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

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

./01cuneus

$1: John  $2: ./01cuneus

答案1

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

但请注意,至少在 Bash 和 Ksh 中,如果没有位置参数,则"${@: -1}"给出"$0",即 shell 名称。这类似于 using${@:0}给出$0所有位置的位置参数。 Zsh 似乎没有提供$0with${@: -1}或 clean ${@[-1]}

这里的问题是这${var:-value}是一个标准扩展,它扩展为默认值价值如果变量未设置或为空。子字符串/数组切片扩展是一种特殊情况,${var:p:n}${@: -1}不是标准的,shell 将其解释${@:-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'

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

相关内容