简体   繁体   English

bash:&&运算符行为

[英]bash: && operator behaviour

I am practicing bash scripting and have a question about && operator 我正在练习bash脚本,并对&&运算符有疑问

As per O'reily bash cookbook if the command before && operator fails the command that precedes it should cease to execute 根据O'reily bash cookbook,如果&&运算符之前的命令失败,那么它之前的命令应该停止执行

See below code 见下面的代码

-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

I expect the rm -rf command to fail as the command cd testdir1 fails, but rm -rf executes and cleans up. 我希望rm -rf命令失败,因为命令cd testdir1失败,但是rm -rf执行并清理。 The behaviour is more like ";" 行为更像是“;” operator . 运营商。

Can someone explain please what am i missing 请有人解释一下,我错过了什么

The issue relates to the exit codes. 该问题与退出代码有关。

The && operator will execute the second command if the first one indicates that it was successful. 如果第一个命令指示它成功,则&&运算符将执行第二个命令。

consider the following: 考虑以下:

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> 

So now consider the following: 所以现在考虑以下内容:

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> 

In this case, because the rm -rf of the nonexistant directory is deemed successful, the next command is executed. 在这种情况下,因为非耐用目录的rm -rf被认为是成功的,所以执行下一个命令。 Whereas rm -r of the same directory is deemed a failure, so the next command is not executed. 而同一目录的rm -r被视为失败,因此不执行下一个命令。

I'm not sure why rm -f returns success when the directory does not exist, one school of thought is that if the directory doesn't exist, then you've achieved the desired outcome of the rm command, so therefore Success! 我不确定为什么当目录不存在时rm -f会返回成功,有一种想法是,如果目录不存在,那么你已经实现了rm命令的预期结果,因此成功! Whereas without the -f option, you are explicitly asking rm to remove something and if it doesn't exist let me know! 而没有-f选项,你明确要求rm删除一些东西,如果它不存在,请告诉我!

BTW. BTW。 There might be an error in your posted code. 您发布的代码中可能存在错误。

You assign a "bad" directory to the variable dir dir=testdir1 . 您将“坏”目录分配给变量dir dir=testdir1 But you cd $dir1 , this is equivalent to cd with no parameters (because the variable dir1 does not exist). 但你cd $dir1 ,这相当于没有参数的cd (因为变量dir1不存在)。 Therefore, it will cd back to your home directory (return value: success). 因此,它将cd回到您的主目录(返回值:成功)。 Running rm -rf * from there might not be the best idea. 从那里运行rm -rf *可能不是最好的主意。

A command fails means that exit code is different from 0. 命令失败意味着退出代码与0不同。

If the command should have failed because the variable is not defined set -o nounset or set -u could be used. 如果命令应该失败,因为未定义变量,则可以使用set -o nounsetset -u

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

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

Checking exit code in documentation or implementation. 检查文档或实现中的退出代码。

from man bash / cd 来自man bash / cd

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

Change the current directory to dir. 将当前目录更改为dir。 if dir is not supplied, the value of the HOME shell variable is the default . 如果未提供dir,则HOME shell变量的值是默认值 Any additional arguments following dir are ignored. dir之后的任何其他参数都将被忽略。 The variable CDPATH 变量CDPATH

defines the search path for the directory containing dir: each directory name in CDPATH is searched for dir. 定义包含dir的目录的搜索路径:在CDPATH中搜索dir的每个目录名称。 Alternative directory names in CDPATH are separated by a colon (:). CDPATH中的备用目录名用冒号(:)分隔。 A null directory name in CDPATH is the same as the current directory, ie, ``.'' . CDPATH中的空目录名与当前目录相同,即“。” If dir begins with a slash (/), then CDPATH is not used. 如果dir以斜杠(/)开头,则不使用CDPATH。 The -P option causes cd to use the physical directory structure by -P选项使cd使用物理目录结构

resolving symbolic links while traversing dir and before processing instances of .. in dir (see also the -P option to the set builtin command); 在遍历dir时和在dir中处理..的实例之前解析符号链接(另请参阅set builtin命令的-P选项); the -L option forces symbolic links to be followed -L选项强制遵循符号链接

by resolving the link after processing instances of .. in dir. 通过在处理dir中的实例后解析链接。 If .. appears in dir, it is processed by removing the immediately previous pathname component from dir, back to a slash or the 如果..出现在目录中,则通过从dir中删除前一个路径名组件,返回斜杠或者来处理它

beginning of dir. dir的开头。 If the -e option is supplied with -P, and the current working directory cannot be successfully determined after a successful directory change, cd will return an unsuccessful 如果-e选项与-P一起提供,并且在成功更改目录后无法成功确定当前工作目录,则cd将返回不成功

status. 状态。 On systems that support it, the -@ option presents the extended attributes associated with a file as a directory. 在支持它的系统上, - @选项将与文件关联的扩展属性显示为目录。 An argument of - is converted to $OLDPWD before the directory change is 在目录更改之前, - 的参数将转换为$ OLDPWD

attempted. 尝试。 If a non-empty directory name from CDPATH is used, or if - is the first argument, and the directory change is successful, the absolute pathname of the new working directory is written 如果使用CDPATH中的非空目录名,或者 - 是第一个参数,并且目录更改成功,则写入新工作目录的绝对路径名

to the standard output. 到标准输出。 The return value is true if the directory was successfully changed; 如果目录已成功更改,则返回值为true; false otherwise. 否则是假的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM