bash 脚本命令以空格分隔

bash 脚本命令以空格分隔

说我有一个 bash 脚本/home/me/test/sh

#!/bin/bash

# cmd                              # here is the output of the cmd
pwd echo 'aaa'                     # /home/me
val=pwd echo 'aaa'                 # aaa
val=pwd echo 'aaa'$val             # aaa

val=pwd echo 'aaa' && echo $val    # aaa <and an empty line>

我不太明白这些用空格分隔的 bash 代码是如何工作的。

顺便说一句,我提出这个问题是因为我刚刚安装了 ROS 并且setup.sh生成了一个名为 bash 的脚本,并且我正在阅读这个脚本。有一行如下:

CATKIN_SHELL=bash /opt/ros/kinetic/_setup_util.py >> file.log

答案1

所以我认为这里让你困惑的是命令格式,其中命令中的第一个单词是变量赋值(shell 根据 . 的存在来确定=

在这些情况下,shell 将评估这些分配,但它会仅有的导出正在运行的命令中的这些变量。特别是,shell 本身无法访问这些变量。

这对于运行受环境变量影响的命令或脚本很有用,在这种情况下,您不需要将它们导出到 shell 中,只需将它们设置为单次执行的“一次性”即可。

让我们分解您的命令并一一解释它们:

pwd echo 'aaa'                     # /home/me

好的,这就是运行pwd命令并向其传递两个参数,echoaaa。但pwd不接受参数,所以它只是忽略这两个并打印本地目录。

val=pwd echo 'aaa'                 # aaa

正如我所解释的,这会执行变量赋值,设置$val为包含字符串pwd,然后echo使用参数执行命令aaa。变量$val可用仅有的echo命令而不是 shell 本身!该echo命令实际上并没有对该变量执行任何操作,因此它只是继续并打印aaa.该命令执行完毕后,$val变量为不是在 shell 中定义。

val=pwd echo 'aaa'$val             # aaa

所以,再次类似于上面的命令。这有点棘手,因为你可能期望决赛$val会扩大。但变量却扩大了通过外壳,而不是通过命令。而且,正如所解释的,shell 并没有真正看到$val哪个设置为pwd,只有命令(在本例中为echo)可以看到,因此$val会扩展为空字符串,这与上面的完全相同。

val=pwd echo 'aaa' && echo $val    # aaa <and an empty line>

还有一次,$val在第一个命令完成后不可用echo,因此第二个命令echo $val将不打印任何内容(只是空行),因为$val在整个执行过程中从未在 shell 本身中真正设置过。

如果您想$val在 shell 中进行设置,那么您需要使该分配成为独立的,而不需要任何命令。例如,这与上面的行为不同:

$ val=pwd; echo 'aaa' && echo $val
aaa
pwd

由于val=pwd后面跟着一个;,那么 shell 会将其视为自己的命令,并将$val在当前 shell 中设置,因此echo $val将按您的预期工作。

(请注意,这里还有一个区别,因为使用 时val=pwd; ...,变量$val并未真正导出,因此echo不是在其环境中查看该变量,同时使用val=pwd echo ...被导出,但在这种情况下,它在 shell 中不可用。)

考虑到您正在使用pwd,我想知道您是否想要将该命令的输出存储在变量中......在这种情况下,您需要使用shell命令替换$(,或者使用反引号,或者更好的是,用and包围命令)

最后一个例子是:

$ val=$(pwd); echo 'aaa' && echo $val
aaa
/home/me

或者:

$ val=$(pwd) && echo 'aaa' && echo $val
aaa
/home/me

(这里有一个微妙的区别,如果替换内的命令(在本例中pwd)失败并以非零状态退出,则后者将中断执行,在这种情况下,以下命令将不会被执行。使用时,;这不是在这种情况下,即使第一个命令失败,也会执行以下命令。)

我希望这能解释您对这些命令不理解的地方!

答案2

下面的代码可能有助于理解这个构造是如何工作的:

$ cd tmprun/
$ cat run.sh 
echo $a
$ ./run.sh 

$ a=bla ./run.sh 
bla

相关内容