【问题标题】:What is the use of the "@a" operator on shell expansions?在 shell 扩展中使用“@a”运算符有什么用?
【发布时间】:2021-03-21 19:35:19
【问题描述】:

我在release notes of Bash 5.1 中看到了这些有趣的项目:

z。 `@a' 变量转换现在打印未设置数组变量的属性。

啊。 `@A' 变量转换现在打印一个声明命令,如果变量具有属性但未设置,则该命令设置变量的属性。

让我们来看看它们是如何工作的。首先,使用 Bash 4.3 查看进度并查看它们曾经产生的相同:

$ declare -A arra=([k1]="v1" [k2]="v2" [k3]="")
$ echo "${arra[@]@a}"
v1 v2
$ echo "${arra[@]@A}"
v1 v2 

现在在 Bash 5.1 中使用 sequence of alternating keys:

$ declare -A arra=(k1 v2 k2 v2 k3)
$ echo "${arra[@]@a}"
A A A
$ echo "${arra[@]@A}"
declare -A arra=([k1]="v1" [k2]="v2" [k3]="" )

所以@A 有助于查看数组的定义,而@a 为每个关联值提供一个“A”。可以? 检查Bash 5.1 Reference Manual → Arrays section 说:

${parameter@operator}

一个
扩展是一个字符串,由代表参数属性的标志值组成。

但我看不出除了“A”之外还有什么可以作为输出。如果我对普通变量使用它,它不会产生任何东西:

$ v=1 $ 回声“${v@a}” # 没有 $ v="你好" $ 回声“${v@a}” # 没有

【问题讨论】:

  • 您将看到 A 以外的输出,例如 declare -i v=1declare -l v="Hello",对于导出的变量:declare -x v=1 也有其用途。
  • 实际上对于所有标志(-n 除外):for f in a A i l n r t u x; do (declare -$f v; echo "$f: ${v@a}"); done。对于变量引用,@a 将显示目标的标志:declare -i a=1; declare -n v=a; echo "${v@a}"
  • @gniourf_gniourf 哦,很有趣。所以我们可以有“A”代表关联数组,“i”代表整数,“il”代表...?,“a”代表数组,“x”代表...
  • 是的,il 很有趣:)。这些标志将以有趣(且不一致)的方式组合(运行我在上一条评论中给出的命令,没有declare 的子shell)。
  • @gniourf_gniourf 相当不错!如果我使用for f in a A i l n r t u x; do declare -$f v; echo "$f: ${v@a}"; done,有些不能一起工作,并且我还会提示错误“bash: declare: `1': invalid variable name for name reference”。无论如何,您评论的是非常好的信息,可以作为一个很好的答案:)

标签: bash


【解决方案1】:

当变量被declare'd 与这些标志时,您将看到除A 之外的其他标志:

$ declare -i v
$ echo "${v@a}"
i
$

declare 知道这些标志:aAilnrtu 和 @987654334 @ 用于描述)。这里有一个小 sn-p 来查看它的实际效果(在新会话中完成,或之前的 unset v):

$ unset v
$ for f in a A i l n r t u x; do (declare -$f v; echo "$f: ${v@a}"); done
a: a
A: A
i: i
l: l
n: 
r: r
t: t
u: u
x: x
$

-n(参考)发生了什么事。在这种情况下,Bash 将返回目标的标志:

$ declare -i a
$ declare -n v=a
$ echo "${v@a}"
i
$

正如 OP cmets 中所注意到的,标志可以以奇怪和不一致的方式组合:

$ # declaring integer AND lowercase
$ declare -il v
$ echo "${v@a}"
il
$ # ???

只是为了好玩:在上一个 sn-p 中删除 declare 的子shell(以便标志组合):

$ unset v
$ for f in a A i l n r t u x; do declare -$f v; echo "$f: ${v@a}"; done
a: a
bash: declare: v: cannot convert indexed to associative array
A: a
i: ai
l: ail
bash: declare: v: reference variable cannot be an array
n: ail
r: airl
t: airtl
u: airtu
x: airtxu
$

(我这样做只是为了好玩,除了 Bash 的一些古怪角落之外,没有展示任何特别之处)。

【讨论】:

猜你喜欢
  • 2019-05-16
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 2016-06-12
  • 1970-01-01
  • 2021-03-29
  • 2022-01-03
相关资源
最近更新 更多