用空格分隔的 bash 脚本命令

Yve*_*ves -2 bash shell-script

说我有一个 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>
Run Code Online (Sandbox Code Playgroud)

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

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

CATKIN_SHELL=bash /opt/ros/kinetic/_setup_util.py >> file.log
Run Code Online (Sandbox Code Playgroud)

fil*_*den 7

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

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

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

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

pwd echo 'aaa'                     # /home/me
Run Code Online (Sandbox Code Playgroud)

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

val=pwd echo 'aaa'                 # aaa
Run Code Online (Sandbox Code Playgroud)

正如我所解释的,这将执行变量赋值,设置$val为包含字符串pwd,然后echo使用aaa参数执行命令。该$val变量可只为echo命令,而不是外壳本身!该echo命令并没有真正对那个变量做任何事情,所以它只是继续并打印aaa. 此命令执行完后,该$val变量未在 shell 中定义。

val=pwd echo 'aaa'$val             # aaa
Run Code Online (Sandbox Code Playgroud)

所以,再次类似于上面的命令。这会变得棘手,因为您可能希望决赛$val得到扩展。但是变量是由 shell扩展的,而不是由命令扩展的。而且,正如所解释的,shell 并没有真正看到$val哪个设置为pwd,只有命令(在这种情况下,echo)才能$val看到,因此被扩展为空字符串,这与上面的完全等效。

val=pwd echo 'aaa' && echo $val    # aaa <and an empty line>
Run Code Online (Sandbox Code Playgroud)

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

如果要$val在 shell 中进行设置,则需要将该分配设为独立的,无需任何命令。例如,这与上述行为不同:

$ val=pwd; echo 'aaa' && echo $val
aaa
pwd
Run Code Online (Sandbox Code Playgroud)

由于val=pwd后跟 a ;,则外壳将其视为自己的命令并将$val在当前外壳中设置,因此echo $val将按预期工作。

(请注意,还有一个区别就在这里,因为用val=pwd; ...的变量$val是不是真的出口,因此echo将不会看到该变量在其环境中,同时与val=pwd echo ...它会得到出口,但随后在这种情况下,它是不具备的外壳。 )

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

最后一个例子:

$ val=$(pwd); echo 'aaa' && echo $val
aaa
/home/me
Run Code Online (Sandbox Code Playgroud)

或者:

$ val=$(pwd) && echo 'aaa' && echo $val
aaa
/home/me
Run Code Online (Sandbox Code Playgroud)

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

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