同时执行多条命令


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

回到顶部
除了可以将要执行的命令集合写入shell script文件外,我们也可以在命令行一次执行多条命令, 那就是通过;, &&, ||这些特殊符号。
cmd ; cmd
分号;前后的两个命令可以没有任何关联。
在某些时候,我们希望可以一次执行多个指令,例如在关机的时候我希望可以先执行两次sync同步 化写入磁盘后才 shutdown 计算机,可以这样做:
[root@initroot ~]# 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)若存在才在该目录底下建立一个文件。由于我们尚未介绍如何判断式 (test) 的使用, 在这里我们使用 ls 以及回传值来判断目录是否存在啦! 让我们进行底下这个练习看看:
范例一:使用 ls 查阅目录 /tmp/abc 是否存在,若存在则用 touch 建立 /tmp/abc/hehe
[peter@study ~]$ ls /tmp/abc && touch /tmp/abc/hehe
ls: cannot access /tmp/abc: No such file or directory
# ls 很干脆的说明找不到该目录,但并没有 touch 的错误,表示 touch 并没有执行
[peter@study ~]$ mkdir /tmp/abc
[peter@study ~]$ ls /tmp/abc && touch /tmp/abc/hehe
[peter@study ~]$ ll /tmp/abc
-rw-rw-r--. 1 peter peter 0 Jul
9 19:16 hehe
看到了吧?如果 /tmp/abc 不存在时,touch 就不会被执行,若 /tmp/abc 存在的话,那么 touch 就会 开始执行啰! 很不错用吧!不过,我们还得手动自行建立目录,伤脑筋~能不能自动判断,如果没 有该目录就给予建立呢? 参考一下底下的例子先:
范例二:测试 /tmp/abc 是否存在,若不存在则予以建立,若存在就不作任何事情
[peter@study ~]$ rm -r /tmp/abc

#先删除此目录以方便测试
[peter@study ~]$ ls /tmp/abc || mkdir /tmp/abc
ls: cannot access /tmp/abc: No such file or directory
#真的不存在喔!
[peter@study ~]$ ll -d /tmp/abc
drwxrwxr-x. 2 peter peter 6 Jul
9 19:17 /tmp/abca
#结果出现了!有进行 mkdir 如果你一再重复『 ls /tmp/abc || mkdir /tmp/abc 』画面也不会出现重复 mkdir 的错误!这是因为 /tmp/abc 已经存在, 所以后续的 mkdir 就不会进行!这样理解否?好了,让我们再次的讨论一下, 如果我想要建立 /tmp/abc/hehe 这个文件, 但我并不知道 /tmp/abc 是否存在,那该如何是好?试看 看:
范例三:我不清楚 /tmp/abc 是否存在,但就是要建立 /tmp/abc/hehe 文件
[peter@study ~]$ 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 被建立起来。
整个流程图示如下:图 10.5.2、指令依序执行的关系示意图
上面这张图显示的两股数据中,上方的线段为不存在 /tmp/abc 时所进行的指令行为,下方的线段则 是存在 /tmp/abc 所在的指令行为。如上所述,下方线段由于存在 /tmp/abc 所以导致 $?=0 ,让中间 的 mkdir 就不执行了! 并将 $?=0 继续往后传给后续的 touch 去利用啦!瞭乎?在任何时刻你都 可以拿上面这张图作为示意! 让我们来想想底下这个例题吧!
例题:
以 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"
这其实是有问题的,为什么呢?由图 10.5.2 的流程介绍我们知道指令是一个一个往后执行, 因此在上面的例子 当中,如果 /tmp/vbirding 不存在时,他会进行如下动作:
1. 若 ls /tmp/vbirding 不存在,因此回传一个非为 0 的数值;
2. 接下来经过 || 的判断,发现前一个指令回传非为 0 的数值,因此,程序开始执行 echo "not exist" ,而 echo "not exist" 程序肯定可以执行成功,因此会回传一个 0 值给后面的指令;
3. 经过 && 的判断,咦!是 0 啊!所以就开始执行 echo "exist" 。
所以啊,嘿嘿!第二个例子里面竟然会同时出现 not exist 与 exist 呢!真神奇~
经过这个例题的练习,你应该会了解,由于指令是一个接着一个去执行的,因此,如果真要使用判断, 那么这个 && 与 || 的顺序就不能搞错。一般来说,假设判断式有三个,也就是:
command1 && command2 || command3
而且顺序通常不会变,因为一般来说, command2 与 command3 会放置肯定可以执行成功的指令, 因此,依据上面例题的逻辑分析,您就会晓得为何要如此放置啰~这很有用的啦!而且.....考试也很 常考~

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读