0

我只想在一行上声明几个变量名。这些名称应该作为已采用的名称可见,即使不一定设置为特定值。

C中,我会这样做:

int i, j, k;

Bash,我被欢迎来到一个惊奇的世界:

declare -a a1 a2 a3; echo ${!a*}

输出:

a1 a2 a3

作品!:) 但这些是数组,所以大概它们是空创建的.. 不是正确的例子。

让我们再试一次。这:

declare -r b1 b2 b3; echo ${!b*}

输出:

<nothing>

但现在:

b1=foo

炸弹:

bash: b1: readonly variable

奇怪的。

它将名称标记为只读,但名称本身不会被${!...}间接看到。

让我想告诉Bash“下定决心!你知道这些符号吗?”

无论如何,这肯定会奏效:

declare -g c1 c2 c3; echo ${!c*}

输出:

<nothing>

最后:

declare -x d1 d2 d3; echo ${!d}

输出:

<nothing>

令人不解的是:

declare -p

看到所有定义的变量,但只有${!...}在它们被赋值时才会被调用打印。但是该man页面并没有说:“那些具有值的名称将被扩展......”。奇怪的。

所以我得出的结论是,这不会像我最初打算的那样声明我的变量名,而且无论如何都是我的目标,因为我没有分配一个值:

declare y1= y2= y3=; echo ${!y*}

...但是,令我沮丧的是,这会产生:

y1 y2 y3

于是问题就变成了:

哪些值在 y1、y2、y3 之后declare y1= y2= y3=

我试图回答自己,因为如果最终被视为可用名称,那么这些变量中肯定有一些东西。甚至,可能是\0价值。他们不应该,以上都没有意义,对吧?

printf "$v1" > /tmp/tmp

给出了这个:

hexdump -C /tmp/tmp
<nothing>

和:

wc -c /tmp/tmp

给出:

0 /tmp/tmp

文件完全为空。

有人明白这个吗?我想做的只是一个C-like int i, j, k;..

我需要它,因为在我的函数中,我通过检查某些变量是否“可见”来非常合理地检查一些用户和环境条件。基于此,脚本会做一些事情并更新这些状态信号变量。应该进入符号表并独立于是否具有值而出现在 declare -p 中的东西只有在它具有值时才会出现在变量名扩展中是不一致的。除了设置值之外,完全空,这使名称再次可见。显然我不能在这里依赖一致的行为?

4

1 回答 1

1

于是问题就变成了:

哪些值在 y1、y2、y3 之后declare y1= y2= y3=

您的问题的答案在于declare -p

cobalt@carbon:~ $ declare foo
cobalt@carbon:~ $ declare -p | grep -- "-- foo"
declare -- foo
cobalt@carbon:~ $ declare foo=
cobalt@carbon:~ $ declare -p | grep -- "-- foo"
declare -- foo=""
cobalt@carbon:~ $ declare -a foo
cobalt@carbon:~ $ declare -p | grep foo
declare -a foo='([0]="")'

${!prefix*}显然只扩展了已声明并分配给它们的值的变量的名称。无论变量是导出的 ( -x) 还是声明的全局 ( -g),简单声明都不会赋值。declare -a var然而,数组变量 ( ) 的声明是不同的,因为它确实分配了一个值。显式分配值 ( declare var=) 的声明也是如此。

于 2013-04-01T10:41:02.863 回答