前言
一般要在服务器上做一些花里胡哨的操作时,都是打开终端(如果是远程服务器,则还需要通过ssh连接下)在上面操作。你会发现当你的ssh断开或关闭terminal时,你在上面临时运行的程序也停掉了,这是为什么呢,今天就来讨论下这个问题。
terminal和shell
关于终端和shell的来由说起来就话长了,这里不做赘述,可以看下这篇文章Linux Cygwin知识库(一):一文搞清控制台、终端、shell概念
简单来说:terminal是帮你输入和显示命令结果的,shell是帮你执行命令的。
从进程会话的角度来说,它们的包含关系如下:
a.out是一个示例程序:
main()
{
while(1){
printf("hello\n");
sleep(10);
};
}
gcc编译后,把它运行起来,看下它的pid,ppid,gid,sid
# pidof a.out
28505
# ps -C a.out -o pid,ppid,gid,sid
PID PPID GID SID
28505 28266 0 28266
可以看到ppid和sid是同一个,是bash
# ps aux | grep 28266
root 28266 0.0 0.0 22872 5436 pts/0 Ss 14:37 0:00 -bash
再看下bash的ppid,以及它对应的进程,可以看到是sshd(我这里是通过ssh连接操作的服务器)
# ps -ef | grep bash
root 28266 28165 0 14:37 pts/0 00:00:00 -bash
# ps -ef | grep 28165
root 28165 1354 0 14:37 ? 00:00:00 sshd: root@pts/0
当关闭a.out的终端时可以看到a.out也没有运行了,而现实的场景中肯定会遇到要守护进程的方式,即终端关掉以后程序可以继续运行。在linux下常见的有daemon,systemed,nohup,后续会一一介绍这些,这里先介绍一个工具tmux。
tmux
在Ubuntu下安装
apt-get install tmux
在centos下安装
yum install tmux
安装完成后,直接运行tmux命令即可进入
此时运行a.out,然后关闭该终端,可以看到a.out还在运行:
# ps aux | grep a.out
root 29299 0.0 0.0 4508 712 pts/2 S+ 15:10 0:00 ./a.out
看下它的父进程:
root@lan-dev-215:~/test# ps -ef | grep 29272
root 29272 29271 0 15:10 pts/2 00:00:00 -bash
root 29299 29272 0 15:10 pts/2 00:00:00 ./a.out
root 29333 28266 0 15:12 pts/0 00:00:00 grep --color=auto 29272
root@lan-dev-215:~/test# ps -ef | grep 29271
root 29271 1 0 15:10 ? 00:00:00 tmux
root 29272 29271 0 15:10 pts/2 00:00:00 -bash
root 29344 28266 0 15:12 pts/0 00:00:00 grep --color=auto 29271
可以看到对应的bash是tmux启动的,我们把tmux杀掉看会怎么样
root@lan-dev-215:~/test# kill -9 29271
root@lan-dev-215:~/test# ps -ef | grep 29271
root 29384 28266 0 15:14 pts/0 00:00:00 grep --color=auto 29271
root@lan-dev-215:~/test# ps -ef | grep a.out
root 29387 28266 0 15:14 pts/0 00:00:00 grep --color=auto a.out
root@lan-dev-215:~/test# ps -ef | grep tmux
root 29390 28266 0 15:14 pts/0 00:00:00 grep --color=auto tmux
可以看到a.out也没了。
到这里我们就明白了:tmux是一个守护进程,不受terminal的影响,从而保证了在它上面运行的程序可以继续运行。
tmux还有非常多的功能,详细了解可以看这里https://github.com/tmux/tmux/wiki