您的位置 首页 > 娱乐休闲

如何在Linux后台运行命令,并且脱离终端后仍在运行

当你在终端上运行一个命令时,如果该命令很快就执行完成,那么没什么可说的,如果该命令是一个耗时操作,或者我们就是要让他一直运行着,那么可能会出现下面问题:

  1. 你的终端一直被该命令占据着
  2. 你的终端充满了很多输出数据或者错误及诊断信息
  3. 如果终端关闭,则程序或命令就会终止

在Unix/Linux中,运行在后台的进程被称为守护进程daemon,通常在后台运行的进程为非交互式,即该进程不会从用户中读取输入。那么如何运行一个命令或程序,使其在后台运行,而无需担心关闭终端程序就结束,同时我们还可以继续做其他事情呢?

nohup ... &

举一个简单的例子,看看如何使用 & 号将下面这个命令放到后台运行:

# cp -R from/data/dir/ to/backup/dir/

这个命令的目的是将from/data/dir/的内容递归地复制到to/backup/dir/中。看起来很简单,但是如果原目录里面的文件太大,在执行过程中终端就会一直被占据。

所以,可以在命令的末尾加上一个 & 号,将这个任务放到后台去执行:

# cp -R from/data/dir/ to/backup/dir/ & [1] 1280

任务被放到后台执行之后,就可以继续在同一个终端上工作了,甚至关闭终端也不影响这个任务的正常执行。

当使用&将一个进程放置到后台运行的时候,shell会提示这个进程的进程ID。在Linux系统中运行的每一个进程都有一个唯一的进程ID,你可以使用进程ID来暂停、恢复或者终止对应的进程,因此进程 ID 是非常重要的。

jobs命令可以显示当前终端正在运行的进程,包括前台运行和后台运行的进程。它对每个正在执行中的进程任务分配了一个序号(这个序号不是进程ID),可以使用这些序号来引用各个进程任务。

# jobs [1]- Running cp -R from/data/dir/* to/backup/dir/ & [2]+ Running find . -iname "*jpg" > to/backup/dir/images.txt &

fg命令可以将后台运行的任务放到前台运行,这样可以比较方便地进行交互。根据jobs命令提供的进程任务序号,再在前面加上% 符号,就可以把相应的进程任务放到前台运行。

# fg %1 #将上面序号为1的cp任务放到前台运行 cp -R from/data/dir/* to/backup/dir/

如果这个进程任务是暂停状态,fg命令会将它启动起来。至此我们知道如何将命令或任务放入后台,提取到前台运行。需要注意的是,如果这个任务有输出内容到标准输出中(例如ping, echo或ls等命令),即使使用了&,也需要等待这些输出任务在前台运行完毕,才可以做其他工作。

这时候我们如果结合nohup命令则可以将标准输出和标准错误输出重定向到no文件中。当我们退出终端或者断开SSH连接时,终端会收到HUP(hangup)信号从而关闭其所有子进程。因此,我们就可以通过让进程忽略HUP信号,也就是nohup的作用了。

# nohup ping www. & [1] 1418 # nohup: ignoring input and appending output to ‘no’

screen / tmux

我们已经知道了如何让进程免受HUP信号的影响,但是如果有大量这种命令需要在稳定的后台里运行,如何避免对每条命令都做这样的操作呢?

此时最方便的方法就是screen了。简单的说,screen 提供了ANSI/VT100的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。screen的参数很多,具有很强大的功能,这里我们就先了解下常用功能:

  • screen -dmS session-name来建立一个处于断开模式下的会话(并指定其会话名)。
  • screen -list 来列出所有会话。
  • screen -r session-name来重新连接指定会话。
  • 快捷键Ctrl-a d 来暂时断开当前会话。
# screen -dmS hello # screen -list There is a screen on: 8824.hello (Detached) 1 Socket in /var/run/screen/S-root. # screen -r hello

当我们用“-r”连接到screen会话后,我们就可以在这个伪终端里面为所欲为,再也不用担心HUP信号会对我们的进程造成影响,也不用给每个命令前都加上“nohup”

让我来看一下下面两个例子,看下screen是如何避免HUP信号的影响

使用&时,进程的进程树

# ping www. & [1] 9499 # pstree -H 9499 init─┬─Xvnc ├─acpid ├─atd ├─2*[sendmail] ├─sshd─┬─sshd───bash───pstree │ └─sshd───bash───ping

未使用screen时我们所处的bash是sshd的子进程,当ssh断开连接时,HUP信号自然会影响到它下面的所有子进程(包括我们建立的ping进程)。

使用screen时的进程树

# screen -r hello # ping www.ibm.com & [1] 9488 # pstree -H 9488 init─┬─Xvnc ├─acpid ├─atd ├─screen───bash───ping ├─2*[sendmail]

此时bash是screen的子进程,而screen是init(PID为1)的子进程。那么当ssh断开连接时,HUP信号自然不会影响到screen下面的子进程了。

然后tmux和screen是实现类似功能的,大家看个人爱好了解选择就好。

最后小结下,如果不需要查看程序的信息输出,并且只是相对耗时的命令任务,可以选择nohup和&的命令组合将任务放到后台执行,如果是大量的命令要在后台稳定执行,并且还经常要调到前台执行,或时常查看,那么可以使用screen或tmux建立新的session的方式来使命令或程序运行于后台。

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“如何通过进程名获取进程id,根据进程名获取进程id,c进程名获取进程pid,通过进程id获取进程窗口”边界阅读