Bash-script 作为 linux-service 无法运行,但从终端执行可以完美运行

Bash-script 作为 linux-service 无法运行,但从终端执行可以完美运行

我有自定义脚本来挂载 Google Drive。
此脚本的一部分是以下代码:

if [ ! "$(which google-drive-ocamlfuse)" ]
then
    echo "Install google-drive-ocamlfuse first!"
    exit 1
fi

从终端执行,效果类似 charm。
因此,我将其配置为服务:

[Unit]
Description=Mount and umount google drives

[Service]
User=<usernamehere>
Type=oneshot
RemainAfterExit=true
ExecStart=/home/<usernamehere>/mybscripts/gdrivemounter.sh -m
ExecStop=/home/<usernamehere>/mybscripts/gdrivemounter.sh -u
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/<usernamehere>/.Xauthority"

[Install]
WantedBy=graphical.target

不幸的是,当我检查服务状态时,我看到退出代码:“首先安装 google-drive-ocamlfuse!”。

命令谷歌驱动器ocamlfuse在用户和根用户下给出了有效路径:

$ which google-drive-ocamlfuse
/home/<usernamehere>/.opam/default/bin/google-drive-ocamlfuse

哪里有问题?

答案1

问题是,当脚本作为服务运行时,它不会以“你”的身份运行:它没有你的环境。具体来说,它没有你的PATH变量。

要么添加/home/<usernamehere>/.opam/default/bin到脚本中的 PATH,要么简单地硬编码该程序的完整路径。

答案2

最可能的原因是包含的目录google-drive-ocamlfuse位于您的登录 shell 中,但不位于所使用的PATH标准中。PATHsystemd

只需在脚本开头添加如下一行:

PATH=$PATH:/path/to/google-drive-ocamlfuse

答案3

感谢大家提供的解决方案。每个解决方案对我来说都很重要,也很有帮助——我又学到了新东西。最后,我决定从 deb 安装 google-drive-ocamlfuse,而不是通过 opam。最好将 gdo 安装在所有用户可用的路径中。因此,不需要额外配置 $PATH。

答案4

笔记:我保留了这个答案,但唯一相关的部分是如何通过服务文件而不是直接在脚本中设置环境。在脚本中设置新的 $PATH 在脚本运行完成后不会保留。

参考其他答案,请不要$PATH通过编辑脚本来污染您的程序,因为实际上如果由正确的用户运行,它就会起作用。如果您必须直接在脚本中编辑它,请通过恢复原始脚本将其放回原处$PATH

我认为问题在于 /etc/profile 未被 systemd 服务处理,因此无论出于什么原因,它都无法获得所需可执行文件的访问权限(或更新的 $PATH)。

为了测试这一点,您可以在错误块中回显 $PATH,如果它缺失,则将其直接添加到 systemd 服务文件中的环境变量中:

[Service]
Environment=PATH=/home/someUser/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

这样,路径仅在脚本运行时更新,而不会为那些可能不希望修改路径的用户修改路径。

相关内容