让Linux服务器后台执行任务

Posted by kevin on November 18, 2019

preface

最近需要在远程调用服务器的 jupyter-notebook 服务,关于怎么搭建 jupyter-notebook 远程服务请看我的这篇文章,每次使用都要开着一个终端才能使用服务,有时候切换一下代理,终端挂了,我就和服务器断开连接了,特别不爽,那么有没有办法在终端关闭之后还继续跑着服务器上的 jupyter-notebook 呢,答案肯定是有的

nohup

nohup 这个命令,就可以在终端退出连接后服务器上依旧在跑着我们的代码,顾名思义,这个命令就表示了 no hangup ,下面我们来看看最基本的使用

首先在服务器上输入下面这句命令,打开 jupyter-notebook 服务,并且让局域网内的用户可以访问

$ nohup jupyter-notebook --ip 0.0.0.0 

这样子的话程序的输出就默认会输出到同级目录的 nohup.out 文件中,并且这个终端也还是被占用了,不能干其他事,因此,上面这样并没有什么卵用

1

想起我们可能用 & 符号让当前任务在后台运行而当前终端可以继续干其他的事,那么在这里道理也是一样的,我们可以写成下面这样

$ nohup jupyter-notebook --ip 0.0.0.0 &

这样子的话,jupyter 就在后台运行,不会影响当前终端,并且退出之后 jupyter-notebook 还在继续运行,依然可以通过主机进行远程访问服务器,此时的输出在 nohup.out 里面

output

我们可以通过 jobs 命令查看当前后台的任务

jobs

但是服务器要是出了什么事,由于什么原因报错了我们是不知道的,因为没有将 stderr 输出,因此,我们最好自己输出错误日志

首先我们再来回顾一下 Linux 的几个标准流,有 stdin , stdout , stderr ,分别用 0 , 1 , 2 表示,因此,我们可以通过标准流的重定向来将标准输出和标准错误重定向到自定义文件中,所以,下面这样子我们就可以捕获到每次的错误信息

$ nohup jupyter-notebook --ip 0.0.0.0 >out.log 2>err.log &

用下面这个也是可以的,将输出和错误信息都重定向到一个文件中( 2>&1 的意思是将 stderr 重定向到 stdout 如果不加 & 的话就会新建一个名为 1 的文件 )

$ nohup jupyter-notebook --ip 0.0.0.0 >jupyter.log 2>&1 &

kill

已经让程序在服务器后台自动运行了,要是我们想关掉应该怎么做呢,上面说到可以用 jobs 命令,但实际上,重新启动一个终端的时候再输入 jobs 是得不到输出的。我之前有一个 shell 脚本叫做 kill.sh,可以直接杀死对应的进程,这里贴出来

#!/bin/bash
#根据进程名杀死进程
if [ $# -lt 1 ]
then
  echo "缺少参数:procedure_name"
  exit 1
fi
 
PROCESS=`ps -ef|grep $1|grep -v grep|grep -v PPID|awk '{ print $2}'`
for i in $PROCESS
do
  echo "Kill the $1 process [ $i ]"
  kill -9 $i
done

使用这个脚本时,直接在终端输入以下命令就能够杀死 jupyter 程序

$ ./kill.sh jupyter-notebook

但是直接这样的话就会有问题,因为我是在学校的服务器上使用,因此不止我一个人在使用,可能其他人也在使用 jupyter-notebook ,例如我现在服务器上就有另外一个人在使用 jupyter-notebook ,要是直接跑脚本就会把这个老哥的 jupyter-notebook 也给 kill 了

pid

所以还是得通过进程 ID 号来杀死我们的程序,虽然有点烦,但是挺保险的

$ ps -ef | grep jupyter-notebook # 找到 PID
$ kill {PID}

reference

https://juejin.im/post/5c7a327d6fb9a049f81a0114

https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/index.html