在后台运行Linux命令的方法
本文探讨了一些如何在后台运行Linux命令,以及如何在终端关闭之后继续运行命令的方法。
一般来讲,我们在终端运行的命令都会将输出打印到终端,在命令结束之后才可以继续运行下一条。这些命令都是运行在前台的。如果你想在命令运行中间的时候做点别的事,除了重新打开一个终端之外,还有以下几种办法。
在后台运行Linux命令
在后台运行命令,只需在命令后加上&
:
1 | [command] & |
例如,sleep 100 &
会让sleep 100
在后台运行,命令行会返回该命令的进程ID:
1 | $ sleep 100 & |
此时输入jobs
,可以看到当前终端正在后台运行的命令,jobs -l
则会显示当前终端在后台运行与已经完成的命令:
1 | $ sleep 100 & |
请注意,这样运行的命令依旧会向终端输出信息,包括标准输入(stdin),标注输出(stdout)与标准错误(stderr)。如果连这也不想要,可以使用如下命令:
1 | [command] > /dev/null 2>&1 & |
/dev/null 2>&1
意味着将stdout
输出到/dev/null
,stderr
输出到stdout
(所以最终都会转移到/dev/null
)。/dev/null
是一个特殊的文件,它可以忽略所有输入的信息。
将前台的Linux命令转至后台
如果在前台已经有运行的命令,可以先用Ctrl + z
将命令中断,然后输入bg
将命令转入后台继续运行。
1 | sleep 100 |
想再将其转为前台运行,输入fg
:
1 | $ fg |
如果有多个在后台运行的任务,需要先用jobs -l
看一下任务编号,再用fg %[job-id]
把需要的任务转到前台(bg
的使用同理):
1 | sleep 100 |
如果需要结束进程,可以使用kill -9 [process-id]
:
1 | sleep 100 & |
让Linux命令在退出终端后仍可继续运行
但是,当任务在后台运行时关闭终端,你会发现任务还是停止了。要让命令在终端结束之后还能继续运行,需要进行disown
。运行disown
之前需要将任务先放入后台。
如果你有多个后台任务,需要先用jobs -l
查看任务编号,再运行disown %[job-id]
。
使用该命令后,该任务会与当前的终端session脱离,这也就意味着jobs -l
里将不会看到该任务,也不能使用fg
、bg
这些命令了。如果你想要看到它,可以使用ps aux
命令,这会列出所有正在运行的进程,无论是否属于该终端。当然,此时关闭终端,该任务不会被挂起,仍会继续运行。
如果你在运行disown
之前没有让任务恢复运行,那么即使你disown
了该任务,任务依旧处于Stopped状态,如果你运行ps ax
,可以看到该任务的状态是T
。在该状态下,只有该任务收到SIGCONT
信号才会继续运行。但是对于disown
之后的任务,无法使用fg
恢复它(因为它已经不属于你)。此时,你可以使用kill -sigcont [process-id]
使它恢复运行。需要注意的是,即使你可以让它恢复运行,也不能撤销disown
的操作,也就是说你无法将该任务带回到你的终端。
当然,你也可以在任务开始之前使用nohup
命令。这个命令会使任务忽略所有的SIGHUP
挂起信号。SIGHUP
就是终端在关闭时会向它所控制的进程发送的终止信号。
1 | nohup [command] & |
命令的输出会被放入nohup.out
文件:
1 | $ nohup sleep 100 & |
你可以用这样的格式忽略所有输出:
1 | nohup [command] > /dev/null 2>&1 & |
当然,把/dev/null
换成别的文件,即可把输出定向至该文件。