颜林林的个人网站

Linux后台运行与虚拟终端

2022-01-24 00:00

Image (题图为Ubuntu Linux终端启动画面)

1

习惯了Windows或Mac OS图形操作界面的朋友,在第一次接触到所谓“前台运行”和“后台运行”的概念时,估计是不容易理解的。在图形界面中,所有程序天然就是并行运行的,通常,打开窗口即运行,关闭窗口即结束,窗口不关闭,扔到一旁,它仍在运行,等着就好。这种符合直觉的优势,让即使没怎么使用过电脑的人,不经培训也能顺利上手,是图形界面的优势。

文本操作界面,或者说命令行操作界面,就没这么友好了。在命令行提示符后面,伴着闪烁的光标,敲入命令,回车,进入等待,命令结束后,重返提示符,可以输入下一条命令。这就是通常的操作过程。学习Linux,最初的场景,也大致如此。

有时候,一条命令的运行时间过长,中途想要退回到提示符,以便运行另一条命令,但同时又不想终止之前正在运行的命令。这就涉及到所谓“前台”与“后台”的概念及操作了。

通常,在命令运行的同时,按下 Ctrl + Z 键,就能把当前正在执行的任务,切换到后台挂起(即暂停定住),并将控制权交回用户,出现提示符,等待输入新命令。为了让被挂起的任务继续执行,通常需要输入命令: $ bg 让任务在后台结束挂起状态,继续执行。这里“bg”是“background”的缩写。 此时,可以通过命令: $ jobs 来查看“当前终端”中,后台正在运行的命令。之所以强调“当前终端”,是因为我们完全可以打开多个终端窗口,并将不同的任务都丢到后台去。而每个终端,将只能看到自己窗口启动的那些任务。

如果是在启动程序时,就希望程序处于后台运行,则直接在原命令的末尾加上一个“&”符号即可。

$ command & 2

通常我们使用Linux系统,都是为了操作远程的高性能计算服务器。通过ssh客户端工具,连上远程服务器,就进入了命令行操作界面,此时即可敲入命令,让命令在服务器上得到执行。

初学者经常误解的一件事,是中途把终端窗口关掉,似乎应该并不会影响服务器上正在运行的任务。其实不然。如果终端窗口中,一条命令正在执行(包括前台和后台方式)的过程中,窗口被关闭,则该命令将会被强行终止。这是由Linux系统本身的设计原理决定的。除了手工关闭窗口外,经常发生的,是网络偶然出现异常发生断开,也会起到类似的窗口被关闭的效果,致使任务被中断。

任何时候,Linux系统在启动一个新程序时,其底层都会调用一个 fork() 函数,该函数会把当前程序的代码段、数据段等全部做拷贝,形成一个新的进程实例,然后才根据需要,从磁盘上装载新程序的代码,放到这个新建的进程实例的空间中。新的进程实例,是以子进程的形式存在的,执行启动新程序的原程序,是它的父进程。Linux中有个基础设定,一旦父进程关闭,它会自动终止并清理掉它所管辖的所有子进程,以确保系统资源都得到回收。

因此,我们通过终端窗口运行的任务,其父进程都是终端shell程序,关闭窗口的时候,shell程序终止,自然也就会把它所启动的所有任务全部终止掉。

为了解决这个问题,早期的Unix或Linux,都会推荐使用nohup命令,来切断对shell父进程的依赖:

nohup command >log.txt 2>log.err & 上述命令中,最开头加上一个“nohup”,能够让启动的任务,不再作为shell程序的子进程,从而避免被误杀。同时末尾加上“&”符号,让该命令自动进入后台,避免受到后续键盘操作的影响,同时也让用户可以重返提示符,继续后续使用。由于完全放弃了对该后台任务的控制,所以有必要通过“>log.txt”和“2>log.err”的设定,来把标准输出和标准错误都写入相应文件中,以便遇到错误时可以获取相关的提示信息(标准输入输出设备相关内容可参见我前面写过的另一篇《深入理解标准输入输出设备》)。

3

不过,nohup已经是过时的用法了。更便利的方法是使用 screen 或 tmux 等命令,启动虚拟终端,来运行所需命令。这些工具都提供随时启动新窗口的功能,极其方便,且不受网络异常和关闭窗口的影响,随时重新连上,都能恢复此前的工作。所以,在虚拟终端中,甚至可以不需要把任务切换到后台,多开几个窗口,让所有任务都放在前台执行即可。

很长时间里,我一直在使用 screen,后来切换到 tmux,觉得后者更加方便,尤其是能够按照需要,水平或垂直地灵活切割窗口界面,让远程的文本操作多任务变得非常顺手。如果两个命令均可用,推荐优先选择 tmux。

最后,分别列举一下这两个命令的常见快捷键:

screen 的快捷键:

ctrl+a, c - 创建新窗口

ctrl+a, " - 列出窗口,进行选择切换

ctrl+a, A - 修改窗口名称

ctrl+a, d - 断开当前终端,下次可使用 screen -r 恢复

tmux 的快捷键:

ctrl+b, c - 创建新窗口

ctrl+b, w - 列出窗口,进行选择切换

ctrl+b, d - 断开当前终端,下次可使用 tmux attach 恢复

ctrl+b, % - 水平切分窗口

ctrl+b, " - 垂直切分窗口

--- END ---

注:本文首发表于“不靠谱颜论”公众号,并同步至本站。