linux后台运行与断开会话运行
linux后台运行命令的两种方式
command &
适合场景:命令还未启动
1 | ./test & |
Ctrl + z
适合场景: 命令已运行
1 | 运行命令 |
这两种方式存在的问题是会话关闭后可能会导致命令停止。
linux关闭会话保持命令运行
关闭会话,发生了什么
步骤1:系统发送Sighup信号给控制进程(通常为shell);
步骤2:控制进程停止,发送Sighup到前台进程和后台进程;
步骤3:子进程收到信号;
步骤4:子进程关闭当前进程;
测试方法
编写一个实时输出的脚本
1 | vim test |
1 | !/bin/bash |
1 | chmod +x test |
另外启动一个控制台实时查看log文件是否有更新
1 | tail -f log |
干涉步骤1,不发送Sighup信号给shell
从根源解决问题,不关闭终端,而是把当前shell隐藏起来。
终端复用软件
screen和tmux是一个终端复用软件,通过该软件能够使终端隐藏起来而不是关闭。
以tmux为例
1 | 进入tmux |
干涉步骤2,不发送信号给当前shell的子进程
不同的shell有不同的实现。
bash: huponexit off
这个是shell的配置,是否在终端退出时发出挂起信号?on为是,off为否
1 | 查看huponexit命令的状态 |
zsh: nohup
1 | 关闭终端退出挂起 |
干涉步骤3,子进程不接收父进程发送过来的信号
setsid
使用该命令运行的命令会运行在init进程中,这就使得命令的运行与当前的shell没有关系了
1 | setsid ./test |
1 | 使用pstree查看,发现进程在init进程上 |

nohup
忽略Sighup信号
1 | nohup ./test.sh |
disown
该命令需要set选项monitor处于开启状态时才能执行
1 | 查看monitor是否开启 |
将任务从当前jobs列表中移除并忽略Sighup信号,但是进程还属于当前shell
1 | 运行任务 |
干涉步骤4,接受父进程发送过来的Sighup信号但是不执行停止的操作
trap
trap 命令用于指定当前进程在接受到信号后将要采取的行动
1 | 设置接受到Sighup执行echo hello |

因为trap的作用域是进程,所以编写一个脚本,使trap和要运行的脚本运行在同一个进程中。
1 | !/bin/bash |