我正在练习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执行并清理。该行为更像是“;”运算符。
有人可以解释一下我想念的东西吗
答案 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 nounset
或set -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。