shell脚本后台运行
凌晨两点,本后服务器上跑着一个数据同步脚本,台运SSH窗口一关,本后进程直接没了。台运这种事我干过不止一次。本后后来学乖了,台运所有耗时超过三十秒的本后脚本,一律扔到后台去。台运 后台运行的本后核心就一个字: 方括号里的本后 重定向是标配。 这样终端就清净了。但还有个隐患:如果你用的是 它还会自动把输出重定向到 后台进程的标准输入默认还是连着终端的。如果脚本里有 还有作业控制。 最后说个真实案例。同事写了个清理临时文件的脚本,用 &。在命令末尾加上它,台运shell会把进程丢到后台,本后终端立刻回到提示符。台运比如:./sync_data.sh & [1] 234561 是作业号,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的作业表了。& 扔到后台,没重定向输出,也没加 nohup。脚本里有个 rm -rf $TMP_DIR/*,而 $TMP_DIR 因为某个条件判断失败变成了空字符串。结果就是 rm -rf /* 在后台悄悄跑了起来。等他发现的时候,/home 已经没了。后台运行不是小事,输出重定向和变量检查,一个都不能省。
-
上一篇
-
下一篇
- 最近发表
- 随机阅读
- 搜索
-
- 友情链接
-