![Systemd 服务启动在启动脚本中找不到命令](https://linux22.com/image/217893/Systemd%20%E6%9C%8D%E5%8A%A1%E5%90%AF%E5%8A%A8%E5%9C%A8%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC%E4%B8%AD%E6%89%BE%E4%B8%8D%E5%88%B0%E5%91%BD%E4%BB%A4.png)
我有一个程序想要作为守护进程运行,我们称之为虚拟程序。我必须解析它的参数,所以我需要一个启动脚本、一个配置文件和程序本身以及它的依赖项,这些都在同一个文件夹中,比如说在/usr/share/dummy
.每个程序、脚本等都是0755。
(是的,我知道这远非完美,通常程序将在bin
、依赖项lib
、配置etc
或其他地方,这只是概念验证守护程序测试。)
程序的服务文件:
[Unit]
Description=Dummy daemon program
After=default.target
[Service]
User=root
ExecStart=/usr/share/dummy/dummyd_start.sh
[Install]
WantedBy=default.target
我的入门脚本(或多或少):
#!/bin/bash
#Some config parsing...
sudo ./dummy $PARAM
我无法从服务文件中调用程序本身,因为目前我需要为其处理参数,并且该程序也需要 root 权限。
如果我只是从其位置 ( sudo ./dummy_start.sh
) 运行启动脚本,它就可以正常工作,启动程序。但如果systemd
启动它,它找不到程序本身:
Mar 10 16:42:52 debian systemd[1]: Started Dummy daemon program.
Mar 10 16:42:52 debian bash[10690]: sudo: ./dummy: command not found
Mar 10 16:42:52 debian systemd[1]: dummy.service: Main process exited, code=exited, status=1/FAILURE
Mar 10 16:42:52 debian systemd[1]: dummy.service: Failed with result 'exit-code'.
如果我更改服务文件调用(例如ExecStart=/bin/bash -c /usr/share/dummy/dummyd_start.sh
.如果我通过完整的绝对路径在启动脚本中调用程序(因此在启动脚本中就像这样sudo ./usr/share/dummy/dummy $PARAM
),它可以找到该程序......但找不到它的依赖项:
Mar 10 16:26:23 debian systemd[1]: Started Dummy daemon program.
Mar 10 16:26:23 debian sudo[10420]: root : PWD=/ ; USER=root ; COMMAND=./usr/share/dummy/dummy -p some_parameters
Mar 10 16:26:23 debian sudo[10420]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=0)
Mar 10 16:26:23 debian bash[10421]: ./usr/share/dummy/dummy: error while loading shared libraries: libmysqlclient.so.21: cannot open shared >
Mar 10 16:26:23 debian sudo[10420]: pam_unix(sudo:session): session closed for user root
Mar 10 16:26:23 debian systemd[1]: dummy.service: Main process exited, code=exited, status=127/n/a
Mar 10 16:26:23 debian systemd[1]: dummy.service: Failed with result 'exit-code'.
有人知道我错过了什么吗?
答案1
代码./dummy $PARAM
想要dummy
在当前目录中查找,无论脚本执行此行时的目录是什么。这是一个常见的误解,认为这可能指的是调用脚本的目录。
我想您可以手动启动脚本,cd /usr/share/dummy; ./dummyd_start.sh
或者通过在文件管理器中单击它来执行类似的操作。
如果您的代码依赖于特定的当前工作目录,则必须使用cd
.
另一种选择是确定正在运行的脚本的位置并将其添加到所有调用的脚本之前。