当我有两个参数时,我正在运行以下代码
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 似乎没有提供$0
with${@: -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}"