在Linux系统中,当我们执行一个命令或启动一个程序时,它默认会运行在前台,占据当前的终端会话。这不仅意味着要等待当前任务完成才能执行下一个命令,更棘手的是,一旦网络连接中断或关闭终端窗口,正在运行的任务也会随之终止。本文将详细介绍如何在Linux后台运行命令,让任务稳定运行,不再依赖终端会话。
1. 理解Linux进程的前台与后台
在Linux系统中,每个命令的执行都会创建一个或多个进程。当我们直接在终端执行命令时,该进程默认运行在前台(foreground)。这意味着:
相比之下,后台进程(background process)则独立于终端运行,释放命令行界面供用户继续操作。这对于执行长时间任务(如数据备份、日志分析、大型文件传输等)尤为重要。
2. 后台进程管理常用命令
| 命令 | 任务 |
|---|
command & | |
echo $! | |
command > /dev/null 2>&1 & | |
jobs -l | |
fg %1 | |
bg %1 | |
Ctrl+Z | |
disown %1 | |
nohup command & | |
kill PID | |
3. 在后台运行命令
3.1 使用&符号
最简单的后台运行方式是在命令末尾添加&符号:
[root@yyzcdb81 ~]# ./backup_monitor.sh &
[1] 1721
[root@yyzcdb81 ~]#
系统会返回两个数字:
[1]:作业ID(Job ID),仅在当前shell会话中有效
3.2 获取后台进程信息
[oracle@yyzcdb81 ~]$ ./expdp_hisdb.sh &
[1] 2118
[oracle@yyzcdb81 ~]$
[oracle@yyzcdb81 ~]$ echo"后台进程PID:$!"
后台进程PID:2118
[oracle@yyzcdb81 ~]$
3.3 输出重定向
后台进程默认仍会向终端输出信息,干扰正常操作。建议将输出重定向:
# 标准实践:丢弃所有输出
$ ./expdp_hisdb.sh > /dev/null 2>&1 &
# 或者保存到日志文件
$ ./expdp_hisdb.sh > expdp_hisdb.log 2>&1 &
注:
> /dev/null丢弃标准输出
2>&1将错误输出重定向到标准输出(已被丢弃),实现静默运行。
4. 管理后台作业
4.1 查看后台作业
使用jobs命令查看当前shell会话中的作业状态:
[oracle@yyzcdb81 ~]$ ./expdp_hisdb.sh > expdb_hisdb.log 2>&1 &
[1] 2576
[oracle@yyzcdb81 ~]$
[oracle@yyzcdb81 ~]$ jobs -l
[1]+ 2576 Running ./expdp_hisdb.sh > expdb_hisdb.log 2>&1 &
[oracle@yyzcdb81 ~]$
输出字段说明:
[1]:作业号,+表示最近操作过的作业,-表示次近的
4.2 前后台切换
# 将后台作业调至前台
$ fg %1
# 将暂停的作业在后台恢复运行
$ bg %2
# 终止后台进程
$ kill 2576 # 优雅终止
$ kill -9 2576 # 强制终止(谨慎使用)
5. 将前台进程移至后台
当忘记使用&运行命令时,可以动态将其移至后台:
(1)暂停进程:按下 Ctrl+Z
$ tar -czf backup.tar.gz /oradata/yyzcdb
^Z
[1]+ 已停止 tar -czf backup.tar.gz /oradata/yyzcdb
(2)转为后台运行:
$ bg
[1]+ tar -czf backup.tar.gz /oradata/yyzcdb &
6. 保持后台进程持续运行
这是运维工作中最关键的部分。默认情况下,退出shell会向所有子进程发送SIGHUP信号,导致进程终止。
6.1 使用disown
disown从shell的作业表中移除进程,使其不再接收shell信号:
$ ./my_task.sh &
[1] 25341
$ disown %1
$ jobs -l # 确认作业已被移除
注意:
disown后进程仍在运行,但输出可能因终端关闭而产生错误。
建议配合输出重定向使用:
$ ./my_task.sh > output.log 2>&1 &
$ disown
6.2 使用nohup
nohup命令让进程忽略SIGHUP信号,并自动处理输出:
$ nohup ./my_task.sh &
nohup: 忽略输入并把输出追加到"nohup.out"
自定义输出文件:
$ nohup ./my_task.sh > mytask.log 2>&1 &
6.3 使用终端复用器(推荐方案)
对于需要交互的长期任务,screen和tmux是更好的选择。
# Screen示例:
$ screen -S backup_session # 创建会话
$ ./interactive_backup.sh # 运行任务
# 按 Ctrl+A 然后按 D 分离会话
$ screen -r backup_session # 重新连接
关于screen命令,请看:
《Linux Screen 命令入门指南》
# Tmux示例:
$ tmux new -s data_processing
$ python process_data.py
# 按 Ctrl+B 然后按 D 分离
$ tmux attach -t data_processing
更多tmux的知识,请看本公众号(haopython)下面文章:
《在 Linux 中管理多个终端会话的Tmux命令示例》
《Linux终端多路复用器Tmux入门指南》
《Tmux 速查手册(附高清PDF文档下载)》
7. 常见问题排查
7.1 "bg: no current job"
当前shell中没有暂停的作业。先使用Ctrl+Z暂停前台进程,或指定具体作业号bg %1。
7.2 "There are stopped jobs when closing terminal"
shell警告存在暂停的作业。处理方式:
$ jobs -l # 查看暂停的作业
$ kill -9 %1 # 终止不需要的作业
# 或者
$ bg %1 && disown %1 # 后台运行并解除关联
7.3 "nohup: failed to open 'nohup.out'"
当前目录无写入权限。解决方案:
$ cd /tmp && nohup ./script.sh & # 切换到可写目录
$ nohup ./script.sh > /tmp/output.log & # 指定输出路径
7.4 进程在退出shell后仍然终止
仅使用&无法防止SIGHUP信号,正确做法:
$ nohup ./script.sh &
# 或者
$ ./script.sh &
$ disown
# 或者使用screen/tmux
8. 最佳实践建议
日志记录:始终将输出重定向到日志文件,便于问题追踪
PID管理:对重要进程记录PID,便于后续管理
资源监控:后台运行大量任务时,注意系统负载
规范命名:使用screen/tmux时给会话起有意义的名称
定期清理:及时清理不需要的后台进程,释放系统资源