如何在Linux后台运行命令(运行命令)

运行命令(如何在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命令则可以将标准输出和标准错误输出重定向到nohup.out文件中。当我们退出终端或者断开SSH连接时,终端会收到HUP(hangup)信号从而关闭其所有子进程。因此,我们就可以通过让进程忽略HUP信号,也就是nohup的作用了。

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

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 -listThere 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.toutiao.com &[1] 9499
# pstree -H 9499init─┬─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 9488init─┬─Xvnc
     ├─acpid
     ├─atd
     ├─screen───bash───ping
     ├─2*[sendmail]

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

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

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

(0)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 PTU@FOXMAIL.COM 举报,一经查实,立刻删除。