【shell&bash进阶系列】(三)SHELL脚本--多命令逻辑执行顺序

Linux中可以使用分号";"、双and号"&&"和双竖线"||"来连接多个命令。单"&"符号也算命令连接符号,只不过它是将其前面的命令放入后台执行,所以可以变相地实现命令并行执行。

1.分号";"

command1 ; command2

命令之间没有逻辑关系。分号连接的命令会按照顺序从前向后依次执行,但分号两端的命令之间没有任何逻辑关系,所有写出来的命令最终都会被执行,即使分号前面的命令出错也不影响后面的命令。

复制代码
[root@xuexi ~]# ls das;echo "hdakl"
ls: cannot access das: No such file or directory

hdakl

2.&&

command1 && command2

逻辑与。&&连接的命令会按照顺序从前向后执行,但只有当command1正确执行才执行command2,如果command1不正确执行,则不执行command2。在bash中,通过预定义变量"?"来判断命令是否正确执行,如果"?"的值为0则表示前一条命令正确执行,其他任意值都表示不正确执行。\

复制代码
[root@xuexi ~]# echo "hdakl" && ls ds 
hdakl
ls: cannot access ds: No such file or directory
复制代码
[root@xuexi ~]# ls das && echo "hdakl"
ls: cannot access das: No such file or directory

3.||

command1 || command2

逻辑或。||连接的命令会按照顺序从前向后执行,但只有当command1不正确执行才执行command2,command1正确执行则不会执行command2。||和&&都是短路符号,符号左右的命令之间具有逻辑关系。

复制代码
[root@xuexi ~]# ls das || echo "hdakl" 
ls: cannot access das: No such file or directory
hdakl
复制代码
[root@xuexi ~]# echo "hdakl" || ls ds   
hdakl

**一般要联合使用&&和||的时候,基本上都会先逻辑与再逻辑或:**command1 && command2 || command3。因为在实际中,command2和command3应该都是想要执行的命令。如果command1正确执行,?就等于0,执行command2,再看情况执行command3,如果command1错误执行,?就不等于0,所以不执行command2,根据$?为非0值,判断了 || 右边的命令应该被执行。

通俗点的理解方法是根据语义判断。"如果...就...否则...就..."的语句使用"cmd1 && cmd2 || cmd3","如果不...就...否则...就..."使用"!cmd1 && cmd2 || cmd3"。

例如,如果用户user1存在,就显示用户已经存在,否则,就添加此用户。

复制代码
[root@xuexi tmp]# id user1 && echo "user1 exists" || useradd user1

如果用户user2不存在,则添加此用户,否则显示用户已存在。

复制代码
[root@xuexi tmp]# !id user2 && useradd user2 || echo "user2 exists"

如果用户user3不存在,则添加此用户,并设定其密码为用户名本身,否则显示用户已存在。

复制代码
[root@xuexi tmp]# !id user3 && useradd user3 && echo "user3" | passwd --stdin user3 || echo "user3 exists"

4.&

command1 &

command1 & command2

&表示将其前面的命令放入后台执行,放入后台后会立即返回到bash环境让用户可以继续和bash交互。如果&符号连接了两个命令,则其前面的命令被放入后台,立即执行后面的命令,所以可以简单地认为这两个命令是并行执行的,两端的命令之间也没有任何逻辑关系。

需要注意的一点是,在终端的bash环境下,子shell中的 后台的进程不受终端控制,在终端被关闭时它会挂靠在init/systemd进程下,因此退出终端或脚本shell环境,无法中断这些后台进程。例如:

复制代码
[root@xuexi ~]# (sleep 10 &)     # 终端1上执行,立即关闭该终端

[root@xuexi ~]# ps aux | grep slee[p]     # 终端2上捕捉sleep进程
root 5732 0.0 0.0 107892 624 ? S 00:28 0:00 sleep 10

注意ps结果中的"?",它表示非终端进程,即脱离了终端。

相关推荐
风虎云龙科研服务器4 分钟前
DeepSeek服务器繁忙之谜:原因与解决方案
运维·服务器·人工智能·科技·深度学习
计算机毕设定制辅导-无忧学长7 分钟前
Git 钩子的应用与自动化流程
运维·git·自动化
亦世凡华、1 小时前
从零开始:使用Jenkins实现高效自动化部署
运维·自动化·jenkins·安装教程·基本使用
forestqq2 小时前
openEuler22.03LTS系统升级docker至26.1.4以支持启用ip6tables功能
linux·运维·docker
xing.yu.CTF2 小时前
2022年中职网络建设与运维赛题-windows服务器解析
运维·服务器·网络·windows·网络建设与运维
x66ccff4 小时前
【GIS】本地部署nominatim地理编码服务
运维
蓝创精英团队4 小时前
基于Ubuntu Ollama 部署 DeepSeek-R132B 聊天大模型(附带流式接口调用示例)
linux·运维·ubuntu·deepseek
下雨天u4 小时前
jenkins手动安装插件
运维·jenkins
渲染101专业云渲染5 小时前
川翔云电脑是什么?租电脑?
运维·服务器·电脑
007php0075 小时前
Docker、Ollama、Dify 及 DeepSeek 安装配置与搭建企业级本地私有化知识库实践
运维·服务器·开发语言·后端·docker·容器·云计算