命令执行的判断依据: ; , &&, ||

    在某些情况下,很多指令我想要一次输入去执行,而不想要分次执行时,基本上只有两个选择, 一个是透过 shell script 撰写脚本去执行,一种则是透过一次输入多重指令!

cmd ; cmd (不考虑指令相关性的连续指令下达)

在某些时候,我们希望可以一次执行多个指令,例如在关机的时候我希望可以先执行两次 sync 同步化写入磁盘后才 shutdown 计算机,那么可以这样做呀: 

[root@www ~]# sync; sync; shutdown -h now

    在指令与指令中间利用分号 (;) 来隔开,这样一来,分号前的指令执行完后就会立刻接着执行后面的指令了。这很方便,换个角度来想,万一我想要在某个目录底下建立一个档案,也就是说,如果该目录存在的话, 那我才建立这个档案,如果不存在,那就算了。 也就是说这两个指令彼此之间是有相关性的, 前一个指令是否成功的执行与后一个指令是否要执行有关!那就得动用到 && 或 || !

$? (指令回传值)     与 &&     或 ||

    如同上面例子谈到的,两个指令之间有相依性,而这个相依性主要判断的地方就在于前一个指令执行的结果是否正确。 还这是我们还要考虑指令回传值了!『 若前一个指令执行的结果为正确,在 Linux 底下会回传一个 $? = 0 的值』。那么我们怎么透过这个回传值来判断后续的指令是否要执行呢?这就得要藉由『 && 』及『 || 』的帮忙了! 注意,两个 & 之间是没有空格的!那个 | 则是 [Shift]+[\] 的按键结果。 

指令下达情况                说明 
cmd1 && cmd2           1. 若 cmd1 执行完毕且正确执行($?=0),则开始执行 cmd2。 
                                       2. 若 cmd1 执行完毕且为错误 ($?≠0),则 cmd2 不执行。 
cmd1 || cmd2              1. 若 cmd1 执行完毕且正确执行($?=0),则 cmd2 不执行。 
                                       2. 若 cmd1 执行完毕且为错误 ($?≠0),则开始执行 cmd2。

    上述的 cmd1 及 cmd2 都是指令。回到我们刚刚假想的情况,就是想要: (1)先判断一个目录是否存在; (2)若存在才在该目录底下建立一个档案。在这里我们使用 ls 以及回传值来判断目录是否存在啦! 让我们进行底下这个练习看看: 

范例一:使用 ls 查阅目录 /tmp/abc 是否存在,若存在则用 touch 建立 /tmp/abc/hehe 
[root@www ~]# ls /tmp/abc && touch /tmp/abc/hehe 
ls: /tmp/abc: No such file or directory 
# ls 很干脆的说明找不到该目录,但并没有 touch 的错误,表示 touch 并没有执行 
[root@www ~]# mkdir /tmp/abc 
[root@www ~]# ls /tmp/abc && touch /tmp/abc/hehe 
[root@www ~]# ll /tmp/abc 
-rw-r--r-- 1 root root 0 Feb 7 12:43 hehe

    如果 /tmp/abc 不存在时,touch 就不会被执行,若 /tmp/abc 存在的话,那么 touch 就会开始执行!不过,我还得手动自行建立目录,如果没有该目录就给予建立呢? 参考一下底下的例子先: 

范例二:测试 /tmp/abc 是否存在,若不存在则予以建立,若存在就不作任何事情 
[root@www ~]# rm -r /tmp/abc                       <==先删除除此目录以方便测试 
[root@www ~]# ls /tmp/abc || mkdir /tmp/abc 
ls: /tmp/abc: No such file or directory           <==真的不存在喔! 
[root@www ~]# ll /tmp/abc 
total 0                                                                 <==结果出现了!有进行 mkdir

    如果你一再重复『 ls /tmp/abc || mkdir /tmp/abc 』画面也不会出现重复 mkdir 的错误!这是因为 /tmp/abc 已经存在, 所以后续的 mkdir 就不会进行!我们再次的讨论一下,如果我想要建立 /tmp/abc/hehe 这个档案, 但我并不知道 /tmp/abc 是否存在,那该如何是好?试看看: 

范例三:我不清楚 /tmp/abc 是否存在,但就是要建立 /tmp/abc/hehe 档案 
[root@www ~]# ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe

    上面这个范例三总是会建立 /tmp/abc/hehe 的!不论 /tmp/abc 是否存在。那么范例三应该如何解释呢? 由于Linux 底下的指令都是由左往右执行的,所以范例三有几种结果我们来分析一下:

      (1)若 /tmp/abc 不存在故回传 $?≠0,则 (2)因为 || 遇到非为 0 的 $? 故开始 mkdir /tmp/abc,由于 mkdir /tmp/abc 会成功进行,所以回传 $?=0 (3)因为 && 遇到 $?=0 故会执行 touch /tmp/abc/hehe,最终 hehe 就被建立了;

      (1)若 /tmp/abc 存在故回传 $?=0,则 (2)因为 || 遇到 0 的 $? 不会进行,此时 $?=0 继续向后传,故 (3)因为 && 遇到 $?=0 就开始建立 /tmp/abc/hehe 了!最终 /tmp/abc/hehe 被建立起来。


例题: 以 ls 测试 /tmp/vbirding 是否存在,若存在则显示 "exist" ,若不存在,则显示 "not exist"! 

答: 这又牵涉到逡辑判断的问题,如果存在就显示某个数据,若不存在就显示其他数据,那我可以这样做: ls /tmp/vbirding && echo "exist" || echo "not exist" 意思是说,当 ls /tmp/vbirding 执行后,若正确,就执行 echo "exist" ,若有问题,就执行 echo "not exist" !那如果写成如下的状况会出现什么?

 ls /tmp/vbirding || echo "not exist" && echo "exist" 这其实是有问题的,为什么呢因为我们知道指令是一个一个往后执行, 因此在上面的例子当中,如果 /tmp/vbirding 不存在时,他会进行如下动作:

1. 若 ls /tmp/vbirding 不存在,因此回传一个非为 0 的数值;
2. 接下来经过 || 的判断,发现前一个指令回传非为 0 的数值,因此,程序开始执行 echo "not exist" ,而 echo "not exist" 程序肯定可以执行成功,因此会回传一个 0 值给后面的指令;
3. 经过 && 的判断,咦!是 0 啊!所以就开始执行 echo "exist" 。

    经过这个例题的练习,你应该会了解,由于指令是一个接着一个去执行的,因此,如果真要使用判断, 那么这个 && 与 || 的顺序就不能搞错。一般来说,假设判断式有三个,也就是: command1 && command2 || command3 而且顺序通常不会变,因为一般来说, command2 与 command3 会放置肯定可以执行成功的指令, 因此,依据上面例题的逡辑分析,您就会晓得为何要如此放置啰~这很有用的啦!而且.....考试也很常考~




你可能感兴趣的:(命令执行的判断依据: ; , &&, ||)