【问题标题】:How is Bash interpreting these statements? [duplicate]Bash 如何解释这些陈述? [复制]
【发布时间】:2015-07-04 07:34:58
【问题描述】:
$ a=one; echo $a  
one
$ a=two echo $a
one  
$ echo $a
one 

a 的值会被初始化为“二”,但为什么显示为“一”?

【问题讨论】:

  • 对我来说很好。 bash-3.2$ a=one bash-3.2$ echo $a one bash-3.2$ a=two bash-3.2$ echo $a two
  • 是的,我同意你的看法,但是我的脚本在 fedora 21 上运行有什么问题?
  • 我可以验证行为,但无法解释。有趣的问题!

标签: linux bash shell


【解决方案1】:

环境变量的同一行初始化仅适用于子shell。

从这些例子中会更加明显:

unset a

a=two echo "<$a>"
<>

a=two bash -c 'echo "<$a>"'
<two>

echo "<$a>"
<>

在第二个 sn-p 中,它打印 &lt;two&gt;,因为我们正在使用 bash -c 生成一个子 shell。

【讨论】:

【解决方案2】:

这是由于 shell 处理替换和变量的顺序。根据POSIX rules for a shell

当需要执行给定的简单命令时(即,当 任何条件构造,例如 AND-OR 列表或 case 语句 没有绕过简单的命令),以下扩展, 分配和重定向都应从 命令文本的开头到结尾:

  1. 根据 Shell 语法规则识别为变量赋值或重定向的单词被保存以供处理 在第 3 步和第 4 步中。

  2. 不是变量赋值或重定向的词应被扩展。如果任何字段在扩展后仍然存在,则第一个 字段应视为命令名称,其余字段为 命令的参数。

  3. 应按照重定向中的说明执行重定向。

  4. 每个变量赋值都应扩展为波浪号扩展、参数扩展、命令替换、算术扩展和 在分配值之前删除引号。

这意味着变量赋值是在参数扩展发生后执行的,例如$a 在处理该命令的 a= 变量分配之前展开。 a 的新值将被传递到命令的执行环境中,但在这种情况下,echo 将没有任何用处。

如果您使用一个尚不存在的变量,您或许可以更好地了解正在发生的事情。

$ unset a
$ a=two echo \($a\)
()
$ a=one
$ a=two echo \($a\)
(one)

下面是一个例子,你可以看到变量赋值被传递到被执行命令的执行环境中:

$ a=one
$ a=two python -c 'import os;print(os.environ["a"])'
two

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    相关资源
    最近更新 更多