Shell(Bash)多命令順序執行方法詳解

2020-07-16 10:04:35
在 Bash 中,如果需要讓多條命令順序執行,則有這樣方法,如表 1 所示。

表 1 多命令順序執行的方法
多命令執行符 格 式 作 用
命令1 ; 命令2 多條命令順序執行,命令之間沒有任何邏輯關係
&& 命令1 && 命令2 如果命令1正確執行($?=0),則命令2才會執行
如果命令1執行不正確($?≠0),則命令2不會執行
II 命令1 || 命令2 如果命令1執行不正確($?≠0),則命令2才會執行
如果命令1正確執行($?=0),則命令2不會執行

";"多命令順序執行

如果使用";"連線多條命令,那麼這些命令會一次執行,但是各命令之間沒有任何邏輯關係,也就是說,不論哪條命令報錯了,後面的命令仍會依次執行。舉個例子:

[[email protected] ~]# ls ; date; cd /user; pwd
anaconda-ks.cfg err.log install.log install.log.syslog list.log out.log
sh
#ls命令正確執行
2013年 10月 21 日星期一 11:35:57 CST
#date命令正確執行
-bash: cd: /user:沒有那個檔案或目錄
#cd命令報錯,因為沒有/user目錄
/root
#雖然cd命令報錯,但是並不影響pwd命令的執行

這就是";"的作用,不論前一條命令是否正確執行,都不影響後續命令的執行。再舉一個例子:

[[email protected] ~]# date; dd if=/dev/zero of=/root/
testfile bs=1k count=100000;
date
#建立一個大小為100MB的檔案,通過";"可以確定需要多長時間
2013 年 10月21日 星期一 11:41:54 CST
#第一條date命令執行
記錄了 100000+0的讀入
記錄了 100000+0的寫出
102400000位元組(102 MB)已複製,2.09394 秒,48.9 MB/秒
#dd命令執行
2013 年 10月 21 日星期一11:41:56 CST #第二條date命令執行,可以判斷dd命令用時2秒
[[email protected] ~]# ll -h testfile
-rw-r--r--. 1 root root 98M 10月21 11:41 testfile
#大小為100MB的testfile檔案已經建立

當我們需要一次執行多條命令,而這些命令之間又沒有可邏輯關係時,就可以使用";"來連線多條命令。

"&&"邏輯與

如果使用"&&"連線多條命令,那麼這些命令之間就有邏輯關係了。只有第一條命令正確執行了,"&&"連線的第二條命令才會執行。那麼,命令 2 是如何知道命令 1 正確執行了呢?

這就需要 Bash 的預定義變數 $? 的支援了,如果 $? 返回值是 0,則證明上一條命令正確執行;如果 $? 返回值是非 0,則證明上一條命令執行錯誤。

舉個例子:

[[email protected] ~]# cp /root/test /tmp/test && rm -rf/ root/test && echo yes
cp:無法獲取"/rooWest"的檔案狀態(stat):沒有那個檔案或目錄
#複製/root/test到/tmp/test,如果命令成功則刪除原檔案,並列印"yes"
#因為/root/test檔案不存在,所以第一條命令執行不正確,第二和第三條命令也都不執行
[[email protected] ~]# ls /tmp/
#在/tmp/目錄中並沒有建立test檔案
[[email protected] ~]# touch /root/test
#建立/root/test檔案
[[email protected] ~]# cp /root/test /tmp/test && rm -rf/ root/test && echo yes
yes
#第一條命令正確執行後,第二和第三條命令都正確執行
#所以列印了"yes"
[[email protected] ~]# ll /root/test
ls:無法存取/root/test:沒有那個檔案或目錄
#原始檔/root/test消失,因為第二條命令rm正確執行
[[email protected] ~]# ll /tmp/test
-rw-r--r--. 1 root root 010月 2113:16/tmp/test
#在/temp/目錄中正確建立了test檔案

再舉一個例子,我們在安裝原始碼包時,需要執行"./configure"、"make"和"make install"命令,但是在安裝軟體時又需要等待較長時間,那麼是否可以利用"&&"同時執行這三條命令呢?當然可以了,命令如下:

[[email protected] ~]# cd httpd-2.2.9
[[email protected] httpd-2.2.9]# ./configure --prefix=/usr/ local/apache2 && make && make install

在這裡,""代表一行命令沒有輸入結束,因為命令太長了,所以加入""字元,可以換行輸入。利用"&&"就可以讓這三條命令同時執行,然後我們就可以休息片刻,等待命令結束。

不過大家請思考一下,這裡是否可以把"&&"替換為或"ll"呢?當然是不行的,這三條安裝命令必須在前一條命令正確執行之後,才能執行後一條命令,如果把"&&"替換為";",則不管前命令是否正確執行,後一條命令都會執行。如果把"&&"替換為"||",則只有前一條命令執行錯誤,後一條命令才會執行。

"||"邏輯或

如果使用"||"連線多條命令,則只有前一條命令執行錯誤,後一條命令才能執行。舉個例子:

[[email protected] ~]#ls /root/test || mkdir/root/tdir
ls:無法存取/root/test:沒有那個檔案或目錄
#因為已經刪除了/root/tesy檔案,所以用ls命令檢視時報錯了
#因為第一條命令執行錯誤,所以第二條命令才正確執行
[[email protected] ~]#ll -d /root/tdir/
drwxr-xr-x. 2 root root 4096 10月21 13:39/root/tdir/
#把root/tdir/目錄已經被建立了

"&&"和"||"非常有意思,如果我們想要判斷某條命令是否正確執行,就可以這樣來做:

[[email protected] ~]# 命令 && echo "yes" || echo "no"

例如:

[[email protected] ~]#ls /root/test && echo "yes"||echo "no"
ls:無法存取/root/test:沒有那個檔案或目錄
no
#因為/root/test檔案不存在,第一條命令報錯,所以,第二條命令不能正確執行
#因為第二條命令執行錯誤,所以第三條命令正確執行,列印"no"
[[email protected] ~]# touch /root/test
[[email protected] ~]# ls /root/test && echo "yes" || echo "no"
/root/test
yes
#因為第一條命令正確執行,所以第二條命令正確執行,列印"yes"
#因為第二條命令正確執行,所以第三條命令執行錯誤