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
How to make Python script run as service?
提问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.py
and 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/restart
the 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 run
function 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.
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 supervisor
package (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 supervisor
to 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.service
and 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