终端和进程的关系
“终端是一个可以与用户进行交互的界面,而bash则是在这个界面上运行的一个程序,负责接收和解释用户的命令。”
终端与bash进程
ps -ef | grep bash
pts(虚拟终端),每连接一个虚拟终端到乌班图linux操作系统,就会出现 一个bash进程(shell[壳]),黑窗口,用于解释用户输入的命令
bash = shell = 命令行解释器
**//whereis bash**
终端上的开启进程
当我们在终端上开启进程时,有一些命令和概念需要了解:
ps -la: 这是一个在Linux和Unix系统中查看进程状态的命令。ps
代表“process status”,即进程状态,而-la
是此命令的两个参数,l
代表long format,显示详细信息,a
代表all,包括所有用户和终端的进程。
man ps: 这个命令用来查看ps
命令的手册页。在Linux和Unix系统中,man
命令是查看系统命令手册的工具。输入man ps
就可以查看ps
命令的详细文档和使用方法。
在终端上运行的进程和终端有紧密的联系。例如,我们在终端上启动了nginx服务,nginx的进程就是由这个终端的bash进程(shell)创建的,因此,nginx进程是bash的子进程。
当我们关闭这个终端时,系统会向bash进程发送一个SIGHUP(Hangup)信号。bash进程接收到这个信号后,会再将此信号发送给其所有子进程,因此,nginx进程也会收到这个SIGHUP信号。默认情况下,进程在接收到SIGHUP信号后会退出,因此,终端关闭时,nginx进程也会随之退出。
这种设计通常是合理的,因为当我们关闭终端时,通常意味着我们不再需要在此终端上启动的进程。然而,有时我们希望即使终端关闭,某些进程(如服务器进程)仍然能继续运行,这时就需要使用一些特殊的方法,如nohup
、disown
或setsid
等命令。
进程关系进一步分析
在Linux系统中,每个运行中的程序都对应一个进程。每个进程都属于一个进程组,这是一个或多个进程的集合,每个进程组有一个唯一的进程组ID。你可以调用系统函数来创建新的进程组或加入已有的进程组。
进程组进一步被组织为会话(session)。一个会话可以包含一个或多个进程组。通常情况下,除非进行特殊的系统函数调用,否则在一个bash(也称为shell)中运行的所有程序都属于同一会话。这个会话有一个称为session leader的进程,通常这个bash就是session leader。你也可以通过调用系统函数创建新的会话。
你可以使用命令ps -eo pid,ppid,sid,tty,pgrp,comm | grep -E 'bash|PID|nginx'
查看不同进程的信息,包括它们的父进程ID、会话ID、所在终端、进程组以及进程名称。
如果你关闭xshell终端,系统就会发送一个SIGHUP信号(终端断开信号)给session leader,即这个bash进程。当bash进程收到SIGHUP信号后,它会将这个信号发送给同一会话中的所有进程。这些进程在收到SIGHUP信号后,如果没有特殊设置,它们的默认行为就是退出。
strace工具的使用
linux下调试分析诊断工具:可以跟踪程序执行时进程的系统调用以及所收到的信号;
#跟踪nginx进程 sudo strace -e trace=signal -p 1359 #发送信号SIGHUP给这个 -1359的绝对值所在的进程组;所以nginx进程就收到了SIGHUP信号 kill(4294965937, SIGHUP)
综合来讲,这个bash先发送SIGHUP给 同一个session里边的所有进程;****然后再发送SIGHUP给自己;
- 终端关闭时如何让进程不退出
设想
- nginx进程拦截(忽略)SIGHUP(nginx收到这个信号并告诉操作系统,我不想死,请不要把我杀死)信号,是不是可以;
- nginx进程和bash进程不再同一个seeion里;
#孤儿进程 #setsid函数不适合进程组组长调用; #setsid命令:启动一个进程,而且能够使启动的进程在一个新的session中,这样的话,终端关闭时该进程就不会退出,试试 setsid ./nginx #nohup(no hang up不要挂断),用该命令启动的进程跟上边忽略掉SIGHUP信号,道理相同 #该命令会把屏幕输出重新定位到当前目录的nohup.out ps -eo pid,ppid,sid,tty,pgrp,comm,cmd|grep -E 'bash|PID|nginx'
后台运行 &
后台执行,执行这个程序的同时,你的终端能够干其他事情;你如果不用 后台执行,那么你执行这个程序后
你的终端就只能等这个程序完成后才能继续执行其他的操作;
fg命令切换到前台
在Linux中,fg
命令用于将一个进程从背景切换到前台。
当你运行一个程序时,它默认为前台运行。如果你想让这个任务“暂停”,可以使用 CTRL+Z 将其置入后台,并且挂起。
然后您就可以执行其它任何工作而不会影响此任务。进行完其他工作之后,就可以通过 fg
命令将短暂放在后台的进程返回到前台来继续执行。
例如:
$ fg %1
上面的命令是把 job number 为 1 的任务转移到前台。
需要注意的是,默认情况下 fg
命令会把最近被放入后台 running 的任务或者最近被 stopped 的任务转至前端。
jobs 命令 列出后台任务
jobs
是一个在 Linux 或 Unix 系统中用来列出当前后台运行的任务的命令。当你使用 CTRL+Z 将一项任务放入后台并挂起,或者用 &
符号让任务在后台运行时,这些任务就被称为 “jobs”。
每个 job 都会被赋予一个 job number,你可以使用这个号码来操作特定的 job。例如,你可以使用 fg %1
命令来将 job number 为 1 的任务切换到前台运行。
jobs
命令会列出所有后台的 jobs,它们的 job number,以及当前的状态(running 或 stopped)。所以,如果你不确定你要切换到前台的任务的 job number,你可以先使用 jobs
命令来查看。
例如:
$ jobs [1] Running my_program & [2]- Stopped my_other_program
上述输出表示当前有两个后台任务:my_program
在后台运行,它的 job number 是 1;my_other_program
被挂起了,它的 job number 是 2。这时候,你就可以使用 fg %1
或者 fg %2
来将这两个任务中的任何一个切换到前台。