令人费解的Bash行为

时间:2013-04-01 03:17:40

标签: bash

我只想在一行上声明一些变量名。这些名称应该是采取的名称,即使不一定设置为特定值。

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&#34;下定决心!你知道这些符号吗?&#34;

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

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*} 页面没有说:&#34;那些有价值的名称将被扩展。&#34;。奇怪。

所以我得出结论,这不会像我最初想要的那样声明我的变量名称,无论如何都是我的目标,因为我没有赋值:

y1 y2 y3

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

declare y1= y2= y3=

所以问题就变成了:

\0之后哪些值有y1,y2,y3?

我试图回答自己,因为如果最终被视为可用名称,则这些变量必须包含一些内容。甚至可能是printf "$v1" > /tmp/tmp 值。如果他们不这样做,上述任何一个都没有意义,对吗?

hexdump -C /tmp/tmp
<nothing>

给出了这个:

wc -c /tmp/tmp

0 /tmp/tmp

给出:

C

文件完全空了。

有人理解这个吗?我想做的就是int i, j, k; - 就像{{1}} ..

我需要它,因为在我的函数中,我通过检查某些变量是否可见&#34;来非常合理地检查一些用户和环境条件。基于此,脚本执行某些操作并更新这些状态信号变量。如果它具有值,那么应该进入符号表并出现在声明-p中的某些内容与变量名称扩展中的某些内容是不一致的。设置值的例外,完全为空,这使名称再次可见。显然,我不能依赖这里的一致行为吗?

1 个答案:

答案 0 :(得分:1)

  

所以问题就变成了:

     

declare y1= y2= y3=之后哪些值有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=)的声明也是如此。