$ {!i}在bash中做什么?在这种情况下,((i + = 1))的影响是什么?

时间:2014-03-14 15:02:04

标签: bash switch-statement

我没有发现任何关于这个含义的内容:

case ${!i} in
     --fa)
       ((i+=1))
       fa=${!i}
       ;;

${!i}的含义是什么? ((i+=1))是什么意思?

2 个答案:

答案 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中的索引数组很稀疏!

算术评估

问题的另一部分实际上是关于算术评估背景的完全不同的问题。有一些上下文,其中名称被视为整数。

  1. 如果它们作为(非关联)数组的索引出现。 ("${foo[i++]}"
  2. 如果它们出现在显式的算术评估上下文中。 ((( i++ ))
  3. 关注let关键字。 (let j++
  4. 如果他们有integer属性。 (declare -i
  5. 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