本文介绍两种执行方式:一种是通过 systemd 执行二进制文件,一种是执行 shell 脚本,在实际使用中可以根据自己需要选择恰当方式。

# 方式一:可执行二进制文件

我们通过 pyinstaller 将单个 python 脚本文件转化为二进制可执行文件,然后再添加到 systemd 服务

pyinstaller 可以将脚本文件转为可执行文件,比如在 windows 环境下,可以将脚本转为.exe 格式的文件,在 linux 环境下,可以转为一个可执行的二进制文件,因为 python 比较简单,我们以 python 为例。

# 创建虚拟环境

创建虚拟环境并通过虚拟环境执行 python 相关操作,可以和外部 python 环境隔离开,降低耦合,消除对系统环境的依赖,避免错误。

[root@localhost jalen]# pwd
[root@localhost jalen]# mkdir test
[root@localhost jalen]# cd test/
[root@localhost test]# whereis python
[root@localhost test]# virtualenv -p /usr/bin/python3.6 venv
[root@localhost test]# source venv/bin/activate

# 生成可执行文件

虚拟环境搭好后,进入虚拟环境。创建简单 python 文件,安装 pyinstaller 依赖。

(venv) [root@localhost test]# python -V
(venv) [root@localhost test]# pip list
(venv) [root@localhost test]# pip install pyinstaller
(venv) [root@localhost test]# touch server.py
(venv) [root@localhost test]# vi server.py    # print ("Hello World!") 随便打印一些
(venv) [root@localhost test]# python server.py
(venv) [root@localhost test]# pyinstaller server.py  # 会生成可执行文件,在 dist 目录下
(venv) [root@localhost test]# ./dist/server/server  # 测试生成的可执行文件

# 创建并启动 systemd 服务

创建.service 服务配置文件,配置服务相关信息,并通过 systemctl 启动该服务

(venv) [root@localhost test]# touch echo-server.service
(venv) [root@localhost test]# vi echo-server.service
(venv) [root@localhost test]# cp echo-server.service /etc/systemd/system
(venv) [root@localhost test]# ls /etc/systemd/system | grep echo-server
(venv) [root@localhost test]# systemctl daemon-reload
(venv) [root@localhost test]# systemctl enable echo-server.service
(venv) [root@localhost test]# systemctl start echo-server.service  
(venv) [root@localhost test]# systemctl status echo-server.service
[Unit]
Description=Service that keeps running the echo-server from startup.
After=network.target

[Install]
WantedBy=multi-user.target

[Service]
Type=simple
ExecStart=/home/jalen/test/dist/server/server   # 这里指向可执行二进制文件,或者是shell脚本
WorkingDirectory=/home/jalen/test/dist/server   # optional
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n

# 查看服务启动后运行日志

这里提供两种方式查看日志,一种是通过 journalctl,一种是 tail log。

(venv) [root@localhost test]# journalctl -f -u echo-server.service  # 查看运行日志
(venv) [root@localhost log]# tail -f /var/log/messages  # 有可能会发现报权限错误,可能是由于 SELinux 安全控制,将可执行文件 copy 到 /usr/local/bin 下再尝试

# 关闭服务

退出虚拟环境,通过命令关闭服务。

(venv) [root@localhost test]# deactivate
[root@localhost test]# systemctl stop echo-server.service
[root@localhost test]# journalctl -f -u echo-server.service
[root@localhost test]# sudo rm /etc/systemd/system/echo-server.service
[root@localhost test]# systemctl daemon-reload
[root@localhost test]# systemctl reset-failed

# 方式二:执行 Shell 脚本

大部分流程和上面一致,只是在 systemd .service 文件里将二进制可执行文件替换为 shell 脚本的路径。

# 创建 shell 脚本

[root@localhost test]# touch server.sh
[root@localhost test]# vi server.sh
#!/bin/bash
SCRIPT_PATH=/home/jalen/test/server.py
PYTHON_PATH=/home/jalen/test/venv/bin/python
$PYTHON_PATH $SCRIPT_PATH
exit 1
[root@localhost test]# chmod +x server.sh
[root@localhost test]# cp server.sh/usr/sbin/  # shell 脚本移动到指定路径
[root@localhost test]# vi echo-server.service   # ExecStart=/usr/sbin/server.sh  # 只需改这行, 后续操作和上面一样

参考:

  • https://abhinand05.medium.com/run-any-executable-as-systemd-service-in-linux-21298674f66f (important)
  • https://serverfault.com/questions/957084/failed-at-step-exec-spawning-permission-denied
  • https://pyinstaller.org/en/stable/#quickstart
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Jalen Chu 微信支付

微信支付

Jalen Chu 支付宝

支付宝

Jalen Chu 公众号

公众号