我们先用cmake编译好一个qt程序
先测试一下能不能运行 ./test
,成功运行
先在/usr/lib/systemd/system
下创建一个env_test.service文件
,内容如下
[Unit]
Description=env_test service
[Service]
Type=oneshot
ExecStart=/home/he/systemd_test/test.sh
[Install]
WantedBy=multi-user.target
其中test.sh内容如下
#!/bin/bash
env >> /home/he/systemd_test/test.log
/home/he/hql/hql_test/code/build/test #启动qt程序
接着试着启动env_test.service
systemctl daemon-reload
systemctl restart env_test.service
systemctl daemon-reload
该命令将会删除先前的单元生成器所创建的所有单元文件与软连接,然后重新运行所有生成器来重新创建单元文件与软连接,最后再让systemd 重新加载所有的单元文件,建议每次更改.service后都来一下;systemctl restart env_test.service
重启服务
然后我们就会发现,诶报错了。通过systemctl status env_test.service
查看,原因就在于并没有该程序能够执行的环境
× env_test.service - env_test service Loaded: loaded (/usr/lib/systemd/system/env_test.service; enabled; preset: disabled) Active: failed (Result: exit-code) since Wed 2024-01-24 15:58:45 CST; 4min 19s ago Process: 10323 ExecStart=/home/he/systemd_test/test.sh (code=exited, status=134) Main PID: 10323 (code=exited, status=134) CPU: 34ms
1月 24 15:58:45 manjaro systemd[1]: Starting env_test service...
1月 24 15:58:45 manjaro test.sh[10326]: Authorization required, but no authorization protocol specified
1月 24 15:58:45 manjaro test[10326]: qt.qpa.xcb: could not connect to display :0
1月 24 15:58:45 manjaro test[10326]: qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
1月 24 15:58:45 manjaro test[10326]: This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may f> Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xco>
1月 24 15:58:45 manjaro test.sh[10323]: /home/he/systemd_test/test.sh: 第 3 行:10326 已放弃 (核心已转储)/home/he/>
1月 24 15:58:45 manjaro systemd[1]: env_test.service: Main process exited, code=exited, status=134/n/a
1月 24 15:58:45 manjaro systemd[1]: env_test.service: Failed with result 'exit-code'.
1月 24 15:58:45 manjaro systemd[1]: Failed to start env_test service.
一个简单粗暴的方法就是将当前终端的环境变量全部写入.service的环境变量,systemd有一套自己的环境变量,通过查看test.log与当前环境变量对比便可得知。
先修改env_test.service,添加环境变量文件test.env([service]部分第二行),EnvironmentFile指定文件后,该服务会去指定文件读取该服务的环境变量,环境变量格式为KEY=VALUE
[Unit]
Description=env_test service
[Service]
Type=oneshot
EnvironmentFile=/home/he/systemd_test/test.env
ExecStart=/home/he/systemd_test/test.sh
[Install]
WantedBy=multi-user.target
将当前环境变量写入test.env,再重启服务
env >> /home/heqinglin/systemd_test/test.env
systemctl daemon-reload
systemctl restart env_test.service
发现成功运行了该qt程序
这样做有没有意义?常规情况来看,如果要开机自启动一个程序的话,还是建议在/etc/profile.d自建shell脚本等等,开机启动读取时会顺便启动。用systemd开机去启动程序并不太好,原因就是因为systemd有不同的环境变量,且开机自启动某些环境变量可能会改变,博主这样做只是为了加深对systemd的理解。
若要开机自启动systemd,则用systemctl enable xxx.service
systemctl enable env_test.service
该举动通过env_test.service
里面[Install]部分的WantedBy=multi-user.target
将env_test.service
通过链接方式放到/etc/systemd/system/multi-user.target.wants
下,也就是说systemctl enable env_test.service
相当于
sudo ln -s /usr/lib/systemd/system/env_test.service /etc/systemd/system/multi-user.target.wants/env_test.service