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

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

问题描述

我没有找到任何关于这个的含义:

I do not find anything about the meaning of this:

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 关键字之后.( 让 j++ )
  4. 如果他们有 integer 属性.(声明 -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.

将名称声明为具有整数属性的一个非常有趣的副作用是它暗示了一种间接扩展形式,与 ${!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.这将导致fa"被设置为命令行上的 next 选项 ($4),因为 i=4 时>fa 已分配.

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天全站免登陆