同时执行多条命令
使用;、&&、||执行多条命令
回到顶部
shell下可以同时输入多条命令,命令之间用()隔开,shell会按照顺序执行命令。如果命令超过了一行,也可以用反斜杠(\)将命令接到下一行。
如果要同时执行多条命令,可以将要执行的命令集合写入shell script文件,也可以通过;、&&或||在命令行中一次执行多条命令。
1.连续执行两条命令:
[root@initroot ~]# cmd1 ; cmd2命令cmd1执行完毕后就会执行cmd2,分号(;)前后的两个命令可以没有任何关联。
2.只有cmd1执行成功($?=0)才会执行cmd2;若cmd1执行出错($?≠0),则cmd2不执行:
[root@initroot ~]# cmd1 && cmd23.只有cmd1执行出错($?≠0),才会执行cmd2;若cmd1执行成功($?=0),则cmd2不执行:
[root@initroot ~]# cmd1 || cmd2变量$?为最近一次命令执行的返回值,通过变量$?可以判断命令执行是否成功,若命令执行成功,则$?=0,如果命令执行出错,则$?!=0。 && 或 ||通过判断$?来决定后续的命令是否执行。
[root@initroot ~]# ls /tmp/initroot ls: cannot access '/tmp/initroot': No such file or directory [root@initroot ~]# echo $? 2 #ls /tmp/initroot的返回值为2,说明该条命令没有执行成功 [root@initroot ~]# cd /home/peter/ [root@initroot ~]# echo $? 0 #cd /home/peter/的返回值为0,说明该条命令执行成功以下是相关的例子:
1.在关机的时候希望可以先执行两次sync,将数据同步写入磁盘后再shutdown计算机:
[root@initroot ~]# sync; sync; shutdown -h now #命令之间用分号(;)隔开,分号前的命令执行完后就会立刻执行后面的命令。2.在某个目录下建立一个文件,需要先判断目录是否存在,只有在目录存在的情况下才建立文件。
除了使用shell判断式(test)判断目录是否存在,也可以使用ls命令执行的返回值来判断目录是否存在:
#使用ls检查目录/tmp/initroot是否存在,若存在则用touch建立/tmp/initroot/haha [peter@study ~]$ ls /tmp/initroot && touch /tmp/initroot/haha ls: cannot access /tmp/initroot: No such file or directory #ls命令和touch命令的执行具有相关性,前一个命令执行成功才会执行后一个命令! #ls提示找不到该目录,说明执行失败,后续的touch不会执行手动建立/tmp/initroot目录后再次运行刚才的命令:
[peter@study ~]$ mkdir /tmp/initroot [peter@study ~]$ ls /tmp/initroot && touch /tmp/initroot/haha [peter@study ~]$ ll /tmp/initroot -rw-rw-r--. 1 peter peter 0 Jul 9 19:16 haha #如果/tmp/initroot不存在,touch就不会被执行,若/tmp/initroot存在,touch就会执行!3.上面的例子需要手动建立/tmp/initroot目录,下面的例子通过ls判断/tmp/initroot是否存在,若不存在则建立:
#先删除/tmp/initroot目录,方便后续操作 [peter@study ~]$ rm -r /tmp/initroot [peter@study ~]$ ls /tmp/initroot || mkdir /tmp/initroot ls: cannot access /tmp/initroot: No such file or directory [peter@study ~]$ ll -d /tmp/initroot drwxrwxr-x. 2 peter peter 6 Jul 9 19:17 /tmp/initroot即使重复执行ls /tmp/initroot || mkdir /tmp/initroot也不会出现重复mkdir的问题!因为再次执行的时候/tmp/initroot已经存在, 所以后续的mkdir就不会执行!
4.判断/tmp/initroot目录是否存在,如果存在则建立/tmp/initroot/haha文件,如果/tmp/initroot目录不存在, 则先建立/tmp/initroot目录后再建立/tmp/ainitroot/haha文件:
[peter@study ~]$ ls /tmp/initroot || mkdir /tmp/initroot && touch /tmp/initroot/haha上述命令无论/tmp/initroot目录是否存在,/tmp/initroot/haha文件都会被成功建立。执行逻辑如下:
(1)如果/tmp/initroot不存在,ls执行失败,返回$?≠0,||判断$?≠0,则执行mkdir /tmp/initroot。 mkdir /tmp/initroot成功执行,mkdir返回$?=0,&&判断$?=0,执行touch /tmp/initroot/haha,最终haha成功建立;
(2)如果/tmp/initroot存在,ls执行成功,返回$?=0,||判断$?=0,不会执行mkdir /tmp/initroot。 此时$?=0会继续传递给&&,&&判断$?=0,则执行touch /tmp/initroot/haha,最终haha成功建立。
5.通过ls判断/tmp/initroot目录是否存在,若存在则显示"exist",若不存在,则显示"not exist":
[peter@study ~]$ ls /tmp/initroot && echo "exist" || echo "not exist" #如果ls /tmp/initroot执行成功,则执行echo "exist",若执行失败则执行echo "not exist" !如果写成如下形式会有问题吗?
[peter@study ~]$ ls /tmp/initroot || echo "not exist" && echo "exist"上面的写法是有问题的,执行逻辑如下:
1) 如果/tmp/initroot存在,则ls执行成功,返回$?=0,||判断$?=0,不执行echo "not exist"。$?=0继续传递给&&,&&判断$?=0,则执行echo "exist";
2) 如果/tmp/initroot不存在,则ls执行失败,返回$?≠0,||判断$?≠0,则执行echo "not exist",echo "not exist"执行成功,返回$?=0并传递给后面的&&。 &&判断$?=0,则执行echo "exist"。
所以上述命令执行完后,如果/tmp/initroot存在,则输出exist,如果不存在,则会同时输出not exist和exist。 这个结果显然是不正确的,所以在使用&&和||执行多条命令的时候,一定要仔细屡清楚命令的执行逻辑!
initroot编辑整理,转载请注明www.initroot.com
100次点赞
100次阅读