公众号旧文
Linux 里 exec bash 和 bash 有什么区别?
我的 usmci-v6-2,前段时间被商家移机到了 us-sjc。
我刚在 Linux 里改了主机名,并执行:
bash

但 AI 却建议我执行
exec bash
那这俩命令,有什么区别?
一、先说结论
bash
作用:启动一个新的 bash 子进程
相当于:
当前 shell
└── 新 bash
而``
exec bash
作用:用 bash 替换当前 shell 进程
相当于:
当前 shell
↓ 替换
新的 bash
不会新增进程层级。
二、最直观的区别
假设 SSH 登录服务器:
root@server:~#
现在执行:
bash
表面看起来没变化。
但实际上已经进入了第二层 shell
如果再执行:
bash
就会:
第一层 shell
└── 第二层 shell
└── 第三层 shell
三、可以像下面这样验证
执行:
echo $SHLVL
正常登录:
1
执行一次 bash:
2

再执行一次:
3
这说明 shell 一层层嵌套了。
四、而 exec bash 不一样
现在重新登录。
执行:
exec bash
再看:
echo $SHLVL
通常还是:
1
因为当前 shell 被替换了,不是新增。
五、为什么 exec 更干净?
因为:
bash
会保留旧 shell。
而:
exec bash
会直接替换当前进程。
这在 Linux 里是非常经典的操作。
六、Linux 底层是进程树
Linux 中每个程序本质上都是进程。
例如:
sshd
└── bash
└── bash
└── bash
你每执行一次:
bash
就会新增一层。
而:
exec bash
是:
旧 bash
↓
新 bash
PID(进程ID)甚至可能不变。
七、什么时候会用 bash?
1. 临时进入新 shell
例如:
bash
测试某些环境变量。
退出:
exit
还能回到原来的 shell。
2. 调试脚本
有时候:
bash script.sh
表示用 bash 解释执行脚本
3. 进入不同环境
例如:
bash --noprofile --norc
可以启动一个干净 shell。
八、什么时候会用 exec bash?
这个更偏运维。
九、修改 hostname 后刷新 shell
例如:
hostnamectl set-hostname us-sjc
当前 shell 提示符可能还是:
root@old-hostname
这时:
exec bash
就能立即刷新。
十、重新加载环境
例如修改:
~/.bashrc
后:
exec bash
可以用新的配置替换当前 shell。
十一、Docker ENTRYPOINT 里经常出现 exec
例如:
exec nginx -g "daemon off;"
原因是让 nginx 成为 PID 1
否则:
shell
└── nginx
信号转发会有问题。
十二、systemd 相关脚本也常用 exec
因为 systemd 更喜欢主程序直接接管进程。
而不是:
shell → shell → shell → 程序
十三、exec 甚至可以替换自己
例如:
exec python3 app.py
执行后当前 shell 消失。
变成:
python3 app.py
直到 Python 退出。
十四、为什么很多运维喜欢 exec?
因为它能避免:
- 多层 shell
- 嵌套混乱
- 进程残留
- 信号问题
- 内存浪费
属于更专业、更 Unix 的写法。
十五、这次遇到的情况
执行:
hostnamectl set-hostname us-sjc
bash
实际上是新开了一层 bash
所以 hostname 刷新了,完全没问题。
只是:
exec bash
会更优雅一点儿。
十六、总结一句话
bash
= 新开一个 shell。
exec bash
= 用新的 bash 替换当前 shell。
十七、一个非常经典的理解方式
把 shell 想象成房间。
bash
像进入房间里的另一个小房间,退出后还能回来。
exec bash
像把当前房间整体改造重建,旧房间直接消失。