凌晨两点,本后服务器上跑着一个数据同步脚本,台运SSH窗口一关,本后进程直接没了。台运这种事我干过不止一次。本后后来学乖了,台运所有耗时超过三十秒的本后脚本,一律扔到后台去。台运
后台运行的本后核心就一个字:
&。在命令末尾加上它,台运shell会把进程丢到后台,本后终端立刻回到提示符。台运比如:./sync_data.sh & [1] 23456方括号里的本后
1是作业号,23456是台运进程PID。看起来挺简单,本后但问题马上来了——脚本的输出还是会往终端上打。你正在敲下一条命令,突然冒出一行日志,烦得很。把输出管住
重定向是标配。
>覆盖写,>>追加写,2>&1把标准错误也合并进去:./sync_data.sh > /var/log/sync.log 2>&1 &这样终端就清净了。但还有个隐患:如果你用的是
nohup之前的普通&,SSH会话断开时,shell会向后台进程发 SIGHUP 信号,进程照样死。nohup 和 disown 的区别
nohup让进程忽略 SIGHUP:nohup ./sync_data.sh > /var/log/sync.log 2>&1 &它还会自动把输出重定向到
nohup.out(如果你没手动指定的话)。我一般都会显式指定日志路径,免得nohup.out散落在各个目录里,过两个月自己都忘了那是什么。disown是另一条路。先用&启动,再用disown -h %1把作业从shell的作业表中移除。区别在于:nohup必须在启动时就用,disown可以事后补救。有次我忘了加nohup,脚本已经跑起来了,就是用disown救回来的。screen 和 tmux 才是长久之计
nohup有个硬伤:你没法再看到脚本的实时输出,也没法交互。数据同步脚本跑一半卡住了,你想看看它到底在干什么,只能去翻日志文件。screen或tmux解决这个问题。开一个会话,在里面跑脚本,然后Ctrl+A D分离。下次screen -r回来,终端状态原封不动。我现在的习惯是:超过五分钟的脚本,一律开tmux。日志照样重定向到文件,但需要的时候能切回去看实时输出。tmux new -s sync ./sync_data.sh 2>&1 | tee /var/log/sync.log # Ctrl+B D 分离tee在这里很好用,输出既打到终端又写进日志。几个容易踩的坑
后台进程的标准输入默认还是连着终端的。如果脚本里有
read之类的操作,它会挂在那里等输入,而你已经切走了。加< /dev/null把标准输入掐掉:nohup ./sync_data.sh < /dev/null > /var/log/sync.log 2>&1 &还有作业控制。
jobs看当前shell的后台作业,fg %1调回前台,bg %1让暂停的作业继续在后台跑。这些命令在nohup启动的进程上不管用——它们已经不属于当前shell的作业表了。最后说个真实案例。同事写了个清理临时文件的脚本,用
顶: 162踩: 21&扔到后台,没重定向输出,也没加nohup。脚本里有个rm -rf $TMP_DIR/*,而$TMP_DIR因为某个条件判断失败变成了空字符串。结果就是rm -rf /*在后台悄悄跑了起来。等他发现的时候,/home已经没了。后台运行不是小事,输出重定向和变量检查,一个都不能省。






评论专区