$ {!i}用bash做什么?在这种情况下,((i + = 1))有什么作用? [英] What does ${!i} do in bash? In that context, what is the effect of ((i+=1))?

查看:499
本文介绍了$ {!i}用bash做什么?在这种情况下,((i + = 1))有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对此一无所知:

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

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

What is the meaning of ${!i}? What is the meaning of ((i+=1))?

推荐答案

间接扩展和名称查找

以惊叹号开始扩展是间接扩展,如下所述.

如果参数的第一个字符是感叹号(!),则会引入变量间接寻址级别. Bash使用由其余参数形成的变量的值作为变量的名称;然后扩展此变量,并在其余替换中使用该值,而不是参数本身的值.这称为间接扩展.例外是${!prefix*}${!name[@]}的扩展,如下所述.感叹号必须紧跟左括号,以引入间接作用.

If the first character of parameter is an exclamation point (!), a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion. The exceptions to this are the expansions of ${!prefix*} and ${!name[@]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection.

间接扩展

因此,如果您有一个声明,如i=foo和另一个声明,如foo=123,则可以通过以下方式引用"foo"的扩展名:

Indirect expansion

So if you have a declaration like i=foo and another like foo=123, you can reference the expansion of "foo" this way:

echo ${!i}

名称枚举

但是,如果您只想知道定义的名称以"i"开头:

Name enumeration

But if you just want to know what defined names start with "i":

$ iPad=123
$ i=foo
$ echo "${!i*}"
i iPad

索引枚举

如果您想知道数组具有哪些索引(或在bash 4关联数组中为键):

Index enumeration

And if you want to know what indices (or, in bash 4 associative arrays, keys) an array has:

$ i=(1 2)
$ i[9]=45
$ echo "${!i[@]}"
0 1 9

请注意,Bash中的索引数组是稀疏的!

Note that indexed arrays in Bash are sparse!

问题的另一部分实际上是关于算术评估上下文的完全不同的问题.在少数情况下,名称被视为整数.

The other part of your question is really a completely different question about the context of Arithmetic Evaluation. There are a handful of contexts where names are treated as integers.

  1. 如果它们作为(非关联)数组的索引出现. ("${foo[i++]}")
  2. 如果它们出现在明确的算术评估上下文中. ((( i++ )))
  3. 跟随let关键字. (let j++)
  4. 如果它们具有integer属性. (declare -i)
  1. If they occur as indices to a (non-associative) array. ("${foo[i++]}")
  2. If they occur in explicit Arithmetic Evaluation context. ((( i++ )))
  3. Following the let keyword. ( let j++ )
  4. If they have the integer attribute. (declare -i)

在运算符上下文中,符号($)是可选的,只要它不模糊即可. (使用$1不带美元符号将是模棱两可的.)实际上,考虑到(( $i++ ))是语法错误,您可能要避免使用它.

The sigil ($) is optional in arithmetic context, as long as it's not ambiguous. (It would be ambiguous to use $1 without the dollar sign.) In fact, you probably want to avoid it, given that (( $i++ )) is a syntax error.

声明名称具有integer属性的一个非常有趣的副作用是,它暗示了一种间接扩展形式,与${!name}表达式不同:

One really interesting side effect to declaring a name to have the integer attribute is that it implies a form of indirect expansion, distinct from the ${!name} expression:

$ aname=123
$ anothername=aname
$ echo $anothername
aname
$ declare -i anothername
$ anothername=aname
$ echo $anothername
123

这里真正发生的是,当anothername声明为整数时,赋值表达式在右侧上具有算术上下文.即使未将aname明确声明为整数,此处也将其视为一个整数.

What's really going on here is that when anothername is declared to be an integer, assignment expressions have arithmetic context on the right hand side. Even though aname wasn't declared explicitly to be an integer, it is treated as one here.

$ anothername=aname++
$ echo $anothername $aname
123 124

有关更多信息,请参见bash手册中的算术评估.

For more information see ARITHMETIC EVALUATION in the bash manual.

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

假设您正在遍历选项,并且$3扩展为--fa.而且,i=3.这将导致在命令行($4)上将 next 选项设置为"fa",因为在分配fa时,已分配i=4.

Let's say you're looping over options, and $3 expands to --fa. But also, i=3. This will cause "fa" to be set to the next option on the commandline ($4), because i=4 by the time fa is assigned.

这篇关于$ {!i}用bash做什么?在这种情况下,((i + = 1))有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆