如何让服务器脚本无限运行

2 投票
4 回答
2540 浏览
提问于 2025-04-15 17:10

我想在一个远程的Linux服务器上无限期地运行一个异步程序。这个脚本本身不会向服务器输出任何东西(除了偶尔向一个mysql数据库写入一些信息)。到目前为止,我找到的唯一选项就是nohup命令:

nohup script_name &

根据我的理解,nohup可以让命令在我退出SSH会话后继续运行,而'&'这个符号则可以让命令在后台运行。我的问题很简单:这样做是否是我想要的最佳方法?我只是想长时间运行一个脚本,偶尔停止它进行更新。

另外,如果nohup确实是最佳选择,那么当我需要终止脚本时,正确的做法是什么?关于如何结束一个nohup进程似乎有一些不同的看法。

谢谢

4 个回答

1

有些情况下,你可能想在远程机器或服务器上执行一些脚本(这些脚本会自动结束),然后再断开与服务器的连接。

比如说:有一个脚本在某台机器上运行,执行时会做以下几件事:1) 拿一个模型并把它复制到一个集群(远程服务器)上;2) 创建一个用于运行模拟的脚本,并把它推送到服务器;3) 在服务器上启动这个脚本,然后断开连接;4) 这个脚本的任务就是在服务器上运行模拟,一旦完成(可能需要几天时间),再把结果复制回客户端。

我会使用以下命令:

ssh remoteserver 'nohup /path/to/script `</dev/null` >nohup.out 2>&1 &'

例如:

echo '#!/bin/bash  
rm -rf statuslist  
mkdir statuslist  
chmod u+x ~/monitor/concat.sh  
chmod u+x ~/monitor/script.sh  
nohup ./monitor/concat.sh &  
' > script.sh 

chmod u+x script.sh

rsync -azvp script.sh remotehost:/tmp

ssh remoteshot '/tmp/script.sh `</dev/null` >nohup.out 2>&1 &'

希望这对你有帮助 ;-)

2

如果你可以修改这个脚本,那你就可以捕捉到 SIGHUP 信号,这样就不需要用 nohup 了。在一个 bash 脚本中,你可以这样写:

trap " echo ignoring hup; " SIGHUP

你也可以用同样的方法来结束程序:捕捉一个比如说 SIGUSR1 的信号,在处理程序中设置一个标志,然后优雅地退出你的主循环。这样,你就可以发送你选择的信号,以一种可预测的方式停止你的程序。

3

你问的基本上是“我怎么创建一个守护进程?”你想要做的就是“守护进程化”,网上有很多相关的例子。这个过程大致是这样的:你先用fork()创建一个子进程,子进程会创建一个新的会话,父进程退出,然后子进程会复制并关闭与控制终端相关的打开文件(也就是标准输入、输出和错误输出)。

有一个叫做python-daemon的包,可以帮你完成这些工作。

如果你想要实现优雅的关闭,可以查看信号库,它可以帮助你创建一个信号处理器。

另外,在网上搜索“python daemon”会找到很多关于常见C语言守护进程化过程的实现例子:http://code.activestate.com/recipes/66012/

撰写回答