用ssh
连接远程服务器时,如果连接断开,那么当前的进程就会被杀死。运行系统备份或ftp传输这样耗时较长的任务,ssh
不方便一直挂着,那该怎么办呢?这种情况的应对方法是GNU Screen,一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。
在执行快速和简单的任务时,往往不会使用screen
,因为这没有必要。但是,如果发现正在运行的任务花费的时间比预期的要长得多,或者只是单纯地忘记了在执行命令前进入screen
,该怎么办呢?这时退出ssh
就会导致前功尽弃。在这种情况下,我们剩下三个选择:
- 一直保持
ssh
连接,但不知道要等到什么时候 - 退出当前进程,丢失所有未保存的工作,并可能浪费大量的时间来处理,或者
- 将正在运行的进程移至新的
screen
中。这是博主将在后文中描述的解决方案。
操作步骤如下。
挂起进程
我们需要做的第一件事是通过按Ctrl+Z挂起当前的进程。
这会向进程发送一个TSTP信号——停止执行进程,并且内核将不再为该进程安排更多的CPU时间。
在后台恢复进程
输入bg
命令。这会将SIGCONT信号发送到该进程,现在它会在后台欢快地运行起来。
disown
进程
现在,我们像这样运行disown
命令:
1 | disown %1 |
disown
从活动作业表中删除该进程,从本质上允许该进程被另一个会话接管。
新开screen
执行screen
即可,进入一个新的screen
会话中。
查找进程的PID
现在,我们需要找到要接管的进程的PID。博主使用和推荐的方法是pgrep
。例如,如果我们的进程称为myprogram
,则可以运行pgrep myprogram
命令,该命令将返回其PID。
使用reptyr
接管进程
最后,我们将PID传递给reptyr
来接管该进程。如果pgrep
给我们的PID为1234,我们现在可以使用以下命令:
1 | reptyr 1234 |
最后两步也可以和在一起:
1 | reptyr $(pgrep myprogram) |