Linux 如何让 Python 脚本作为服务运行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16420092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:53:21  来源:igfitidea点击:

How to make Python script run as service?

pythonlinuxcentos

提问by Filipe Tagliacozzi

I want to run a python script in a CENTOS server:

我想在 CENTOS 服务器中运行一个 python 脚本:

#!/usr/bin/env python
import socket
try:    
    import thread 
except ImportError:
    import _thread as thread #Py3K changed it.
class Polserv(object):
    def __init__(self):
        self.numthreads = 0
        self.tidcount   = 0
        self.port       = 843
        self.sock       = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind(('100.100.100.100', self.port))
        self.sock.listen(5)
    def run(self):
        while True:
            thread.start_new_thread(self.handle, self.sock.accept()) 
    def handle(self,conn,addr):
        self.numthreads += 1
        self.tidcount   += 1
        tid=self.tidcount
        while True:
            data=conn.recv(2048)
            if not data:
                conn.close()
                self.numthreads-=1
                break
            #if "<policy-file-request/>
python myscript.py start
python myscript.py stop
python myscript.py restart
" in data: conn.sendall(b"<?xml version='1.0'?><cross-domain-policy><allow-access-from domain='*' to-ports='*'/></cross-domain-policy>") conn.close() self.numthreads-=1 break #conn.sendall(b"[#%d (%d running)] %s" % (tid,self.numthreads,data) ) Polserv().run()

Im using $ python flashpolicyd.pyand it works fine... The question is: How to keep this script running even after I close the ssh console?

我正在使用$ python flashpolicyd.py并且它工作正常......问题是:即使在我关闭 ssh 控制台后如何保持这个脚本运行?

采纳答案by eandersson

I use thiscode to daemonize my applications. It allows you start/stop/restartthe script using the following commands.

我使用代码来守护我的应用程序。它允许您start/stop/restart使用以下命令编写脚本。

import sys
import time

from daemon import Daemon


class YourCode(object):
    def run(self):
        while True:
            time.sleep(1)


class MyDaemon(Daemon):
    def run(self):
        # Or simply merge your code with MyDaemon.
        your_code = YourCode()
        your_code.run()


if __name__ == "__main__":
    daemon = MyDaemon('/tmp/daemon-example.pid')
    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            daemon.start()
        elif 'stop' == sys.argv[1]:
            daemon.stop()
        elif 'restart' == sys.argv[1]:
            daemon.restart()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)

In addition to this I also have an init.dscript for controlling my service. This allows you to automatically start the service when your operating system boots-up.

除此之外,我还有一个用于控制我的服务的init.d脚本。这允许您在操作系统启动时自动启动服务。

Here is a simple example to get your going. Simply move your code inside a class, and call it from the runfunction inside MyDeamon.

这是一个简单的例子来帮助你前进。一个简单的类中移动你的代码,然后从它调用run函数中MyDeamon

start on started sshd
stop on runlevel [!2345]

exec /usr/bin/python /opt/my_service.py
respawn

Upstart

暴发户

If you are running an operating system that is using Upstart (e.g. CentOS 6) - you can also use Upstart to manage the service. If you use Upstart you can keep your script as is, and simply add something like this under /etc/init/my-service.conf

如果您运行的操作系统使用 Upstart(例如 CentOS 6) - 您也可以使用 Upstart 来管理服务。如果您使用 Upstart,您可以保持脚本不变,只需在下面添加类似的内容/etc/init/my-service.conf

start my-service
stop my-service
restart my-service

You can then use start/stop/restart to manage your service.

然后您可以使用 start/stop/restart 来管理您的服务。

e.g.

例如

sudo apt-get install supervisor

A more detailed example of working with upstart is available here.

此处提供与 upstart 合作的更详细示例。

Systemd

系统化

If you are running an operating system that uses Systemd (e.g. CentOS 7) you can take a look at the following Stackoverflow answer.

如果您运行的操作系统使用 Systemd(例如 CentOS 7),您可以查看以下Stackoverflow 答案

回答by pztrick

I offer two recommendations:

我提供两个建议:

supervisord

主管

1) Install the supervisorpackage (more verbose instructions here):

1)安装supervisor包(这里有更详细的说明):

[program:flashpolicyd]
directory=/path/to/project/root
environment=ENV_VARIABLE=example,OTHER_ENV_VARIABLE=example2
command=python flashpolicyd.py
autostart=true
autorestart=true

2) Create a config file for your daemon at /etc/supervisor/conf.d/flashpolicyd.conf:

2)为您的守护进程创建一个配置文件/etc/supervisor/conf.d/flashpolicyd.conf

supervisorctl update
supervisorctl restart flashpolicyd

3) Restart supervisorto load your new .conf

3)重新启动supervisor以加载新的.conf

[Unit]
Description=My Python daemon

[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/project/main.py
WorkingDirectory=/opt/project/
Environment=API_KEY=123456789
Environment=API_PASS=password
Restart=always
RestartSec=2

[Install]
WantedBy=sysinit.target


systemd (if currently used by your Linux distro)

systemd(如果您的 Linux 发行版当前使用)

import os
pid = os.getpid()
op = open("/var/us.pid","w")
op.write("%s" % pid)
op.close()

Place this file into /etc/systemd/system/my_daemon.serviceand enable it using systemctl daemon-reload && systemctl enable my_daemon && systemctl start my_daemon --no-block.

将此文件放入/etc/systemd/system/my_daemon.service并使用systemctl daemon-reload && systemctl enable my_daemon && systemctl start my_daemon --no-block.

To view logs:

查看日志:

systemctl status my_daemon

systemctl status my_daemon

回答by Arsalan

first import os module in your app than with use from getpid function get pid's app and save in a file.for example :

首先在您的应用程序中导入 os 模块,而不是使用 getpid 函数获取 pid 的应用程序并保存在文件中。例如:

PATHAPP="/etc/bin/userscript.py &"
PIDAPP="/var/us.pid"
case  in 
        start)
                echo "starting"
                $(python $PATHAPP)
        ;;
        stop)
                echo "stoping"
                PID=$(cat $PIDAPP)
                kill $PID
        ;;

esac

and create a bash file in /etc/init.d path: /etc/init.d/servername

并在 /etc/init.d 路径中创建一个 bash 文件:/etc/init.d/servername

python flashpolicyd.py &

now , u can start and stop ur app with down command:

现在,您可以使用 down 命令启动和停止您的应用程序:

service servername stop service servername start

服务服务器名停止服务服务器名开始

or

或者

/etc/init.d/servername stop /etc/init.d/servername start

/etc/init.d/servername 停止 /etc/init.d/servername 启动

回答by shookees

My non pythonic approach would be using & suffix. That is:

我的非 Pythonic 方法是使用 & 后缀。那是:

killall flashpolicyd.py

To stop the script

停止脚本

python flashpolicyd.pi & disown

also piping & suffix with disown would put the process under superparent (upper):

带有 disown 的管道和后缀也会将进程置于父级(上)之下:

start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --exec $DAEMON

回答by Rodrigo Navarrete

for my script of python, I use...

对于我的python脚本,我使用...

To START python script :

启动 python 脚本:

PID=$(cat $PIDFILE)
kill -9 $PID
rm -f $PIDFILE

To STOP python script :

停止 python 脚本:

##代码##

P.S.: sorry for poor English, I'm from CHILE :D

PS:对不起,英语不好,我来自智利:D