这是调用脚本的特定于 bash 的方法吗:VARIABLE=value bash somescript

这是调用脚本的特定于 bash 的方法吗:VARIABLE=value bash somescript

我一生都在使用 HPUX/ksh shell,所以现在的 bash 似乎正在提出许多新的方式来做很多事情(其中许多似乎不符合 POSIX 标准 - 例如 'mkdir -p /root/{abc,def,ghi,jkl}' - 显然这是 bash/OpenStack 中的编码指南最佳实践 - 但这完全是另一回事)。

无论如何,我已经在 OpenStack 代码中的多个地方看到了这种脚本的执行:

ENABLE_VCENTER=true bash /root/stack_install.sh

有人能解释一下这是如何工作的吗——我知道 shell 将设置变量,然后调用 shell 脚本(这是 nooB 犯的经典错误,解释了为什么变量赋值不应该带空格——例如 HELLO=world)。但内部究竟发生了什么?

另外,为什么当我尝试这个命令时它似乎对我不起作用:

HELLO=world echo $HELLO

我从 shell 获得以下输出:

[ ubuntuOne : /home/bumblebee ]
> HELLO=world echo $HELLO


[ ubuntuOne : /home/bumblebee ]
> 

我在这里遗漏了什么?

谢谢您的回复。

答案1

HELLO=world echo $HELLO

在上述语句中,bash在执行语句之前进行参数扩展。这意味着$HELLO在执行语句(包括将 HELLO 设置为world)之前, 将被替换为空(或 HELLO 的当前值)。

观察:

$ HELLO=world bash -c 'echo $HELLO'
world

请注意,它echo $HELLO在单引号内。单引号可防止参数扩展。这意味着,直到bash子 shell 启动并将其视为参数时,才会对 HELLO 进行求值。到那时,HELLO 将被设置为等于world

相比之下,请考虑这一行,其中单引号已被双引号替换:

$ HELLO=world bash -c "echo $HELLO"

这里什么都没打印出来,因为双引号不会抑制参数扩展。因此,命令bash被赋予了两个参数-cecho。因此,什么都没打印出来。

所有血腥细节

man bash详细解释处理上述命令时发生的情况:

当执行简单命令时,shell 从左到右执行以下扩展、分配和重定向。

   1.     The words that  the  parser  has  marked  as  variable
          assignments  (those  preceding  the  command name) and
          redirections are saved for later processing.

   2.     The words that are not variable assignments  or  redi‐
          rections  are  expanded.   If  any  words remain after
          expansion, the first word is taken to be the  name  of
          the command and the remaining words are the arguments.

   3.     Redirections  are  performed  as described above under
          REDIRECTION.

   4.     The text after  the  =  in  each  variable  assignment
          undergoes  tilde  expansion, parameter expansion, com‐
          mand substitution,  arithmetic  expansion,  and  quote
          removal before being assigned to the variable.

再次考虑该命令:

HELLO=world echo $HELLO

参数echo在步骤 2 中经历了参数扩展,而bash直到步骤 4 才开始为 HELLO 分配新值。

相关内容