Shell(Bash)多命令顺序执行方法详解

在 Bash 中,如果需要让多条命令顺序执行,则有这样方法,如表 1 所示。

表 1 多命令顺序执行的方法
多命令执行符 格 式 作 用
命令1 ; 命令2 多条命令顺序执行,命令之间没有任何逻辑关系
&& 命令1 && 命令2 如果命令1正确执行($?=0),则命令2才会执行
如果命令1执行不正确($?≠0),则命令2不会执行
II 命令1 || 命令2 如果命令1执行不正确($?≠0),则命令2才会执行
如果命令1正确执行($?=0),则命令2不会执行

";"多命令顺序执行

如果使用";"连接多条命令,那么这些命令会一次执行,但是各命令之间没有任何逻辑关系,也就是说,不论哪条命令报错了,后面的命令仍会依次执行。举个例子:

[root@localhost ~]# 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命令的执行

这就是";"的作用,不论前一条命令是否正确执行,都不影响后续命令的执行。再举一个例子:

[root@localhost ~]# 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秒
[root@localhost ~]# ll -h testfile
-rw-r--r--. 1 root root 98M 10月21 11:41 testfile
#大小为100MB的testfile文件已经建立

当我们需要一次执行多条命令,而这些命令之间又没有可逻辑关系时,就可以使用";"来连接多条命令。

"&&"逻辑与

如果使用"&&"连接多条命令,那么这些命令之间就有逻辑关系了。只有第一条命令正确执行了,"&&"连接的第二条命令才会执行。那么,命令 2 是如何知道命令 1 正确执行了呢?

这就需要 Bash 的预定义变量 $? 的支持了,如果 $? 返回值是 0,则证明上一条命令正确执行;如果 $? 返回值是非 0,则证明上一条命令执行错误。

举个例子:

[root@localhost ~]# cp /root/test /tmp/test && rm -rf/ root/test && echo yes
cp:无法获取"/rooWest"的文件状态(stat):没有那个文件或目录
#复制/root/test到/tmp/test,如果命令成功则删除原文件,并打印"yes"
#因为/root/test文件不存在,所以第一条命令执行不正确,第二和第三条命令也都不执行
[root@localhost ~]# ls /tmp/
#在/tmp/目录中并没有建立test文件
[root@localhost ~]# touch /root/test
#建立/root/test文件
[root@localhost ~]# cp /root/test /tmp/test && rm -rf/ root/test && echo yes
yes
#第一条命令正确执行后,第二和第三条命令都正确执行
#所以打印了"yes"
[root@localhost ~]# ll /root/test
ls:无法访问/root/test:没有那个文件或目录
#源文件/root/test消失,因为第二条命令rm正确执行
[root@localhost ~]# ll /tmp/test
-rw-r--r--. 1 root root 010月 2113:16/tmp/test
#在/temp/目录中正确建立了test文件

再举一个例子,我们在安装源码包时,需要执行"./configure"、"make"和"make install"命令,但是在安装软件时又需要等待较长时间,那么是否可以利用"&&"同时执行这三条命令呢?当然可以了,命令如下:

[root@localhost ~]# cd httpd-2.2.9
[root@localhost httpd-2.2.9]# ./configure --prefix=/usr/ local/apache2 && make && make install

在这里,"\"代表一行命令没有输入结束,因为命令太长了,所以加入"\"字符,可以换行输入。利用"&&"就可以让这三条命令同时执行,然后我们就可以休息片刻,等待命令结束。

不过大家请思考一下,这里是否可以把"&&"替换为或"ll"呢?当然是不行的,这三条安装命令必须在前一条命令正确执行之后,才能执行后一条命令,如果把"&&"替换为";",则不管前命令是否正确执行,后一条命令都会执行。如果把"&&"替换为"||",则只有前一条命令执行错误,后一条命令才会执行。

"||"逻辑或

如果使用"||"连接多条命令,则只有前一条命令执行错误,后一条命令才能执行。举个例子:

[root@localhost ~]#ls /root/test || mkdir/root/tdir
ls:无法访问/root/test:没有那个文件或目录
#因为已经删除了/root/tesy文件,所以用ls命令查看时报错了
#因为第一条命令执行错误,所以第二条命令才正确执行
[root@localhost ~]#ll -d /root/tdir/
drwxr-xr-x. 2 root root 4096 10月21 13:39/root/tdir/
#把root/tdir/目录已经被建立了

"&&"和"||"非常有意思,如果我们想要判断某条命令是否正确执行,就可以这样来做:

[root@localhost ~]# 命令 && echo "yes" || echo "no"

例如:

[root@localhost ~]#ls /root/test && echo "yes"||echo "no"
ls:无法访问/root/test:没有那个文件或目录
no
#因为/root/test文件不存在,第一条命令报错,所以,第二条命令不能正确执行
#因为第二条命令执行错误,所以第三条命令正确执行,打印"no"
[root@localhost ~]# touch /root/test
[root@localhost ~]# ls /root/test && echo "yes" || echo "no"
/root/test
yes
#因为第一条命令正确执行,所以第二条命令正确执行,打印"yes"
#因为第二条命令正确执行,所以第三条命令执行错误

编程帮,一个分享编程知识的公众号。跟着站长一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

文章不深奥,不需要钻研,在公交、在地铁、在厕所都可以阅读,随时随地涨姿势。

文章不涉及代码,不烧脑细胞,人人都可以学习。

当你决定关注「编程帮」,你已然超越了90%的程序员!

编程帮二维码
微信扫描二维码关注