我没有发现任何关于这个含义的内容:
case ${!i} in
--fa)
((i+=1))
fa=${!i}
;;
${!i}
的含义是什么?
((i+=1))
是什么意思?
答案 0 :(得分:4)
${!i}
指的是名称为$i
的变量。它被称为变量间接。请参阅示例以使其更清晰:
$ i="hello" # variable $i contains 'hello'
$ hello="bye" # variable $hello contains 'bye'
$ echo "${!i}" # when doing variable expansion of $i, it fetches $hello
bye
关于((i+=1))
,它是一种增加变量i
的方法。参见:
$ i=3
$ ((i+=1))
$ echo $i
4
您也可以使用以下任何一种:
i=$((i+1))
((i++))
let "i=i+1"
有关详细信息,请参阅Bash Reference Manual - Shell Parameter Expansion:
如果参数的第一个字符是感叹号(!),则a 引入了变量间接的级别。 Bash使用的值 由参数的其余部分形成的变量作为名称 变量;然后展开此变量,并在该变量中使用该值 其余的替换,而不是参数本身的值。 这称为间接扩展
答案 1 :(得分:4)
使用感叹号开始扩展是间接扩展,如下所述。
如果参数的第一个字符是感叹号(!),则引入一个变量间接的级别。 Bash使用从参数的其余部分形成的变量的值作为变量的名称;然后展开此变量,并将该值用于替换的其余部分,而不是参数本身的值。这被称为间接扩张。例外情况是下文所述
${!prefix*}
和${!name[@]}
的扩展。感叹号必须紧跟左括号以引入间接。
因此,如果您有i=foo
之类的声明和foo=123
之类的声明,则可以参考" foo"这样:
echo ${!i}
但是,如果您只是想知道定义的名称以" i":
开头$ iPad=123
$ i=foo
$ echo "${!i*}"
i iPad
如果你想知道一个数组有哪些索引(或者在bash 4关联数组中,键):
$ i=(1 2)
$ i[9]=45
$ echo "${!i[@]}"
0 1 9
请注意,Bash中的索引数组很稀疏!
问题的另一部分实际上是关于算术评估背景的完全不同的问题。有一些上下文,其中名称被视为整数。
"${foo[i++]}"
)(( i++ ))
)let
关键字。 (let j++
)integer
属性。 (declare -i
) sigil($
)在算术上下文中是可选的,只要它不含糊不清即可。 (如果没有美元符号,使用$1
将是不明确的。)事实上,考虑到(( $i++ ))
是语法错误,您可能希望避免它。
声明名称具有整数属性的一个非常有趣的副作用是它暗示了一种间接扩展形式,与${!name}
表达式不同:
$ aname=123
$ anothername=aname
$ echo $anothername
aname
$ declare -i anothername
$ anothername=aname
$ echo $anothername
123
这里真正发生的事情是,当anothername
被声明为整数时,赋值表达式在右侧上具有算术上下文。尽管aname
未明确声明为整数,但在此处将其视为一个整数。
$ anothername=aname++
$ echo $anothername $aname
123 124
有关详细信息,请参阅bash手册中的ARITHMETIC EVALUATION。
case ${!i} in
--fa)
((i+=1))
fa=${!i}
;;
我们假设您正在循环选项,$3
会扩展为--fa
。但是,i=3
。这将导致" fa"要在命令行($4
)上设置为 next 选项,因为i=4
分配了fa
。