bash:&&操作员行为

时间:2019-05-14 10:09:17

标签: linux bash

我正在练习bash脚本,对&&运算符有疑问

根据O'reily bash食谱,如果&&运算符之前的命令使该命令之前的命令失败,则应停止执行

请参见下面的代码

-bash-4.2$ pwd
/home/postgres
-bash-4.2$ mkdir testdir
-bash-4.2$ dir=testdir1
-bash-4.2$ cd $dir1 && rm -rf *
-bash-4.2$ echo $?
0
-bash-4.2$ ls

我希望rm -rf命令失败,因为命令cd testdir1失败,但是rm -rf执行并清理。该行为更像是“;”运算符。

有人可以解释一下我想念的东西吗

2 个答案:

答案 0 :(得分:1)

问题与退出代码有关。

如果第一个命令成功,则&&运算符将执行第二个命令。

请考虑以下内容:

gmc@linux-ihon:/tmp> rm -rf nonexistant
gmc@linux-ihon:/tmp> echo $?     # Note that there is no error message and the exit status is 0 (success).
0
gmc@linux-ihon:/tmp> rm -r nonexistant
rm: cannot remove 'nonexistant': No such file or directory
gmc@linux-ihon:/tmp> echo $?     # Note that there was an error message and the exit status is 1 (unsuccessful)
1
gmc@linux-ihon:/tmp> 

因此,请考虑以下内容:

gmc@linux-ihon:/tmp> rm -rf nonexistant && echo "rm success"
rm success
gmc@linux-ihon:/tmp> rm -r nonexistant && echo "rm success"
rm: cannot remove 'nonexistant': No such file or directory
gmc@linux-ihon:/tmp> 

在这种情况下,由于认为不存在的目录的rm -rf成功,因此将执行下一个命令。 而同一目录的rm -r被视为失败,因此不会执行下一个命令。

我不确定为什么当目录不存在时rm -f返回成功,一种思路是,如果目录不存在,那么您已经达到了rm命令的预期结果,因此成功!而如果没有-f选项,则您明确要求rm删除某些内容,如果不存在,请告诉我!

顺便说一句。您发布的代码中可能有错误。

您为变量dir dir=testdir1分配了一个“坏”目录。但是您cd $dir1相当于没有参数的cd(因为变量dir1不存在)。因此,它将CD返回到您的主目录(返回值:成功)。从那里运行rm -rf *可能不是最好的主意。

答案 1 :(得分:0)

命令失败意味着退出代码不同于0。

如果由于未定义变量而导致命令失败,则可以使用set -o nounsetset -u

set -u
cd "$dir1"
echo "$?"

set +u   # disable nounset
cd "$dir1"
echo "$?"

检查文档或实施中的退出代码。

来自man bash / cd

  

cd [-L | [-P [-e]] [-@]] [dir]

     

将当前目录更改为dir。 如果未提供dir,则HOME shell变量的值为默认值。 dir之后的所有其他参数都将被忽略。变量CDPATH

     

定义包含dir的目录的搜索路径:在CDPATH中的每个目录名称中搜索dir。 CDPATH中的备用目录名称用冒号(:)分隔。      CDPATH中的空目录名称与当前目录相同,即``。''。如果dir以斜杠(/)开头,则不使用CDPATH。 -P选项使cd使用以下物理目录结构

     

在遍历dir时以及在dir中处理..实例之前解析符号链接(另请参见set Builtin命令的-P选项); -L选项强制遵循符号链接

     通过在目录中处理..实例后解析链接。如果..出现在dir中,则通过从dir中删除紧接的先前路径名组件,返回斜杠或

来进行处理。      

dir的开头。如果-P随附了-e选项,并且在成功更改目录后无法成功确定当前的工作目录,则cd将返回失败的

     

状态。在支持该功能的系统上,-@选项将与文件关联的扩展属性显示为目录。 -的参数在目录更改为之前先​​转换为$ OLDPWD

     

尝试过。如果使用CDPATH中的非空目录名,或者-作为第一个参数,并且目录更改成功,那么将写入新工作目录的绝对路径名

     

到标准输出。 如果目录已成功更改,则返回值为true;否则为false。否则为false。