如何通过nohup在CentOS上确保进程中断后仍能稳定运行,让工作无忧?
- 内容介绍
- 文章标签
- 相关推荐
在CentOS上使用 nohup让进程即使终端关闭也能稳定运行
在日常运维或开发工作中,最让人抓狂的往往是进程因为意外断开终端、网络波动或登录会话失效而中止。这会导致长时间任务被迫重新启动、数据不完整甚至业务中断。
1️⃣ 痛点一:终端关闭后进程瞬间挂掉
很多同事习惯直接在交互式 shell 中执行长任务。但一旦 SSH 断开,SIGHUP 信号会把这些进程全部杀死,导致工作“半路被砍”。
2️⃣ 痛点二:输出被塞满终端,日志难以追踪
默认情况下命令的标准输出和错误都会直接打印到当前终端。话说回来,若在后台运行,这些信息会丢失或混乱,使得排错变得异常困难。
3️⃣ 痛点三:不当使用导致僵尸进程或资源泄漏
如果没有正确地将子进程从父 shell 中分离。或者忘记重定向文件描述符,就可能出现僵尸进程,占用程序 PID 表并影响后续任务。其实,
什么是 nohup?说起来,为什么它能解决上述痛点?
nohup是 Linux/Unix 程序自带的工具。它会:
-
拦截并忽略
SIGHUP信号,让程序即使在使用者注销后仍保持运行。 -
默认把标准输出和标准错误(
stderr) 重定向到当前目录下的nohup.out文件,避免信息丢失。 -
配合后台符号
&使用。 可让命令立即返回 shell,继续做别的事。
# 常见提示
再看nohup,ignoring input and appending output to 'nohup.out'
# 常见提示
再看nohup,ignoring input and appending output to 'nohup.out'
这行提示说明输出已经安全地写入了 nohup.out
从一步步实战来看。用 nohup 把任务跑起来并确保它“不死”
a) 基本语法 & 输出重定向
# 将脚本放到后台运行,并把所有日志写入自定义文件
nohup ./my_script.sh> /var/log/my_script.log 2>&1 &
* 解释:
-
/var/log/my_script.log: 自定义日志方法,便于日后查看。 -
2>&1: 把错误流合并到同一个文件。老实说, -
&: 将进程放入后台。让 shell 立即可用。
b) 快速测试:让一个简单命令跑一小时
# 让进程睡眠 3600 秒,即使关掉终端也不受影响
nohup sleep 3600> /tmp/sleep.log 2>&1 &
# 查看后台作业
jobs -l
# 或者直接通过 ps 查询
ps aux | grep sleep
c) 防止产生僵尸进程 – 使用 dissown
If you already started a job without NoHUP。you can detach it:
# 假设已有后台作业 %1 disown %1 # 此后即使关闭终端,该作业也不会收到 SIGHUP
如何安全地停止一个已经用 nohup 启动的进程?
- # 查找 PID:
- # 杀死进程:
- # 验证是否已停止:
# 示例:查找名为 my_script.sh 的进程 ps aux | grep my_script.sh | grep -v grep | awk '{print $2}'
# 用普通信号先尝试优雅退出 kill -15 # 若仍未结束。再强制杀死 kill -9
# 搜索确认 PID 已不存在 ps -p && echo "still running" || echo "stopped"
TIPS & BEST PRACTICES
-
A. 永远显式重定向日志: 不要依赖默认生成的
nohup.out 否则多个任务会共用同一个文件,混淆日志。 -
B. 为关键任务加上监控脚本: 使用
crontab -e 或 systemd 服务来周期性检查 PID 是否存活;若异常自动重启, - C. 使用 systemd 替代 nohup: 对生产环境推荐编写 unit 文件,这样可以获得更完善的日志、自动重启和资源限制功能。其实,
- D. 避免使用 “>” 连续追加同一日志文件: 长期追加会导致单个日志文件膨胀。建议配合 logrotate 定期切割。
- E. 对于交互式程序,请改为非交互模式或使用 screen/tmux 再配合 nohup。
从完整示例来看,在 CentOS 上部署一个长期运行的数据同步脚本
# 假设脚本方法 /opt/scripts/sync_data.sh # 1️⃣ 创建专属日志目录 mkdir -p /var/log/sync_job # 2️⃣ 使用 nohup 启动并记录完整日志 nohup /opt/scripts/sync_data.sh \ --source db1 \ --target db2 \ > /var/log/sync_job/stdout.log 2>&1 & # 3️⃣ 把作业从当前 shell 中移除 disown # 4️⃣ 检查是否成功启动 ps -ef | grep sync_data.sh | grep -v grep # 5️⃣ 如需停止: PID=$ kill -15 $PID # 优雅退出 sleep 5 kill -9 $PID # 强制结束
在CentOS上使用 nohup让进程即使终端关闭也能稳定运行
在日常运维或开发工作中,最让人抓狂的往往是进程因为意外断开终端、网络波动或登录会话失效而中止。这会导致长时间任务被迫重新启动、数据不完整甚至业务中断。
1️⃣ 痛点一:终端关闭后进程瞬间挂掉
很多同事习惯直接在交互式 shell 中执行长任务。但一旦 SSH 断开,SIGHUP 信号会把这些进程全部杀死,导致工作“半路被砍”。
2️⃣ 痛点二:输出被塞满终端,日志难以追踪
默认情况下命令的标准输出和错误都会直接打印到当前终端。话说回来,若在后台运行,这些信息会丢失或混乱,使得排错变得异常困难。
3️⃣ 痛点三:不当使用导致僵尸进程或资源泄漏
如果没有正确地将子进程从父 shell 中分离。或者忘记重定向文件描述符,就可能出现僵尸进程,占用程序 PID 表并影响后续任务。其实,
什么是 nohup?说起来,为什么它能解决上述痛点?
nohup是 Linux/Unix 程序自带的工具。它会:
-
拦截并忽略
SIGHUP信号,让程序即使在使用者注销后仍保持运行。 -
默认把标准输出和标准错误(
stderr) 重定向到当前目录下的nohup.out文件,避免信息丢失。 -
配合后台符号
&使用。 可让命令立即返回 shell,继续做别的事。
# 常见提示
再看nohup,ignoring input and appending output to 'nohup.out'
# 常见提示
再看nohup,ignoring input and appending output to 'nohup.out'
这行提示说明输出已经安全地写入了 nohup.out
从一步步实战来看。用 nohup 把任务跑起来并确保它“不死”
a) 基本语法 & 输出重定向
# 将脚本放到后台运行,并把所有日志写入自定义文件
nohup ./my_script.sh> /var/log/my_script.log 2>&1 &
* 解释:
-
/var/log/my_script.log: 自定义日志方法,便于日后查看。 -
2>&1: 把错误流合并到同一个文件。老实说, -
&: 将进程放入后台。让 shell 立即可用。
b) 快速测试:让一个简单命令跑一小时
# 让进程睡眠 3600 秒,即使关掉终端也不受影响
nohup sleep 3600> /tmp/sleep.log 2>&1 &
# 查看后台作业
jobs -l
# 或者直接通过 ps 查询
ps aux | grep sleep
c) 防止产生僵尸进程 – 使用 dissown
If you already started a job without NoHUP。you can detach it:
# 假设已有后台作业 %1 disown %1 # 此后即使关闭终端,该作业也不会收到 SIGHUP
如何安全地停止一个已经用 nohup 启动的进程?
- # 查找 PID:
- # 杀死进程:
- # 验证是否已停止:
# 示例:查找名为 my_script.sh 的进程 ps aux | grep my_script.sh | grep -v grep | awk '{print $2}'
# 用普通信号先尝试优雅退出 kill -15 # 若仍未结束。再强制杀死 kill -9
# 搜索确认 PID 已不存在 ps -p && echo "still running" || echo "stopped"
TIPS & BEST PRACTICES
-
A. 永远显式重定向日志: 不要依赖默认生成的
nohup.out 否则多个任务会共用同一个文件,混淆日志。 -
B. 为关键任务加上监控脚本: 使用
crontab -e 或 systemd 服务来周期性检查 PID 是否存活;若异常自动重启, - C. 使用 systemd 替代 nohup: 对生产环境推荐编写 unit 文件,这样可以获得更完善的日志、自动重启和资源限制功能。其实,
- D. 避免使用 “>” 连续追加同一日志文件: 长期追加会导致单个日志文件膨胀。建议配合 logrotate 定期切割。
- E. 对于交互式程序,请改为非交互模式或使用 screen/tmux 再配合 nohup。
从完整示例来看,在 CentOS 上部署一个长期运行的数据同步脚本
# 假设脚本方法 /opt/scripts/sync_data.sh # 1️⃣ 创建专属日志目录 mkdir -p /var/log/sync_job # 2️⃣ 使用 nohup 启动并记录完整日志 nohup /opt/scripts/sync_data.sh \ --source db1 \ --target db2 \ > /var/log/sync_job/stdout.log 2>&1 & # 3️⃣ 把作业从当前 shell 中移除 disown # 4️⃣ 检查是否成功启动 ps -ef | grep sync_data.sh | grep -v grep # 5️⃣ 如需停止: PID=$ kill -15 $PID # 优雅退出 sleep 5 kill -9 $PID # 强制结束

