描述
通过 ssh 命令远程登录到 CPU 使用率很高(90%以上)的机器,以 debug 模式(-x)执行 bash 脚本时,你会发现,一些扔到后台执行的命令不会被执行到。
复盘
- 使用 stress 命令将机器的 CPU 压到百分之 90 以上。
stress --cpu [机器的核数]
- 脚本 test.sh
echo "这是一个测试的脚本"
echo "Hello World!" > tmp.log 2>&1 &
- ssh 远程执行命令
ssh host 'sh -x test.sh'
你会发现,不会生成 tmp.log 文件。
解释
我们知道,当我们再 bash 上将一个命令扔到后台执行时,bash 其实是会 fork 一个进程出来,然后在此子进程上执行相关的命令。我们也知道,Linux 是一个操作系统,进程的运行是需要 OS 来进行调度的。当你 fork 一个进程出来之后,该进程能不能马上执行是取决于进程的调度情况的(具体如何调度,得深挖)。导致上述诡异的现象的原因,就在于我们通过 ssh 以 debug 模式运行 bash 脚本,在 CPU 繁忙的时候后台的进程并不会立马执行。这样就会使得当我的 test.sh 脚本执行完了,echo "Hello World!" > tmp.log 2>&1
这条命令还未开始执行。由于 test.sh 进程跟后台进程存在一种父子关系,当 test.sh 的进程退出之后,后台进程也就退出了,命令并不会执行。
解决办法
稍微延迟 test.sh 的退出时间,例如在 test.sh 最后加上:
sleep 0.01