systemd 与普通 shell 执行比较?

systemd 与普通 shell 执行比较?

我正在尝试让 systemd 服务在启动时每 x 分钟运行一个脚本。脚本中的步骤之一是设置 VPN 连接;当作为 systemd 服务运行时,此步骤会失败。

服务文件:

[Unit]
Description=Run the checkvpn bash script

[Service]
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ExecStart=/usr/local/bin/checkvpn.sh

定时器文件

[Unit]
Description=checkvpn service timer

[Timer]
OnActiveSec=60
OnCalendar=*-*-* *:*:00
Unit=checkvpn.service

[Install]
WantedBy=multi-user.target

bash 脚本:

#!/bin/bash -l
if [ "$EUID" -ne 0 ]
  then echo "Please run as root"
  exit
fi

isVpnConnected() {
  if [[ $(cyberghostvpn --status) =~ "Wireguard connection found" ]]; then
    return 0
  else
    return 1
  fi
}

isDockerRunning() {
  if [[ $(docker ps) =~ "some-docker-image" ]]; then
    return 0
  else 
    return 1
  fi
}

if isVpnConnected; then
  if isDockerRunning; then
    echo "vpn and docker ok"
  else
    echo "vpn ok, but docker is not running, starting docker ..."
    docker-compose -f /home/davy/git/nookie-config/docker-compose.yaml up -d
  fi
else
  echo "vpn not ok, connecting ..."
  cyberghostvpn --traffic --wireguard --country-code ES --connect
  if isVpnConnected; then
    if isDockerRunning; then
      echo "vpn restored, but docker was still running without vpn"
    else
      echo "vpn fixed, restarting docker ..."
      docker-compose -f /home/davy/git/nookie-config/docker-compose.yaml up -d
    fi
  else
   echo "unable to fix vpn, stopping dockers ..."
   docker-compose -f /home/davy/git/nookie-config/docker-compose.yaml down
  fi
fi

我得到的错误:

Feb 12 14:14:02 nookie checkvpn.sh[8490]: Traceback (most recent call last):
Feb 12 14:14:02 nookie checkvpn.sh[8490]:   File "cyberghostvpn.py", line 5, in <module>
Feb 12 14:14:02 nookie checkvpn.sh[8490]:   File "<frozen importlib._bootstrap>", line 991, in _find_and_load
Feb 12 14:14:02 nookie checkvpn.sh[8490]:   File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
Feb 12 14:14:02 nookie checkvpn.sh[8490]:   File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
Feb 12 14:14:02 nookie checkvpn.sh[8490]:   File "/usr/local/lib/python3.8/dist-packages/PyInstaller/loader/pyimod03_importers.py", line 623, in exec_module
Feb 12 14:14:02 nookie checkvpn.sh[8490]:   File "configs/base.py", line 3, in <module>
Feb 12 14:14:02 nookie checkvpn.sh[8490]:   File "configs/base.py", line 12, in BaseConfiguration
Feb 12 14:14:02 nookie checkvpn.sh[8490]: TypeError: can only concatenate str (not "NoneType") to str
Feb 12 14:14:02 nookie checkvpn.sh[8490]: [8490] Failed to execute script cyberghostvpn

显然,cyberghost cli 实用程序是用 python 编写的,并且无法导入某些内容。我假设 systemd 环境与我的用户环境不同,但我不知道具体是什么。我还尝试提供与我的用户环境中的路径变量相同的路径变量,但这并没有解决任何问题。

有任何想法吗?

davy@nookie 的输出:~$ sudo find / -name "cybergho*"

    /home/davy/cyberghostvpn-ubuntu-20.04-1.3.4
    /home/davy/cyberghostvpn-ubuntu-20.04-1.3.4/cyberghost
    /home/davy/cyberghostvpn-ubuntu-20.04-1.3.4/cyberghost/cyberghostvpn
    /home/davy/cyberghost
    find: ‘/proc/6687’: No such file or directory
    /usr/bin/cyberghostvpn
    /usr/local/cyberghost
    /usr/local/cyberghost/cyberghostvpn
    /etc/wireguard/cyberghost.conf

答案1

我假设 systemd 环境与我的用户环境不同,但我不知道是什么方式。

您可以通过(非常)简短的脚本找到答案:

#!/bin/bash
printenv > /home/davy/environment_"$( date +%s )"

该脚本执行printenv命令,该命令列出所有环境变量,然后将输出保存到/home/davy/environment_xxxxxxxxxx,其中xxxxxxxxxx文件名的一部分是以秒为单位的当前 Unix 时间戳(我选择这个特殊文件名的唯一原因是每次执行脚本时文件都不会被覆盖,但名称和保存位置显然可以更改为您想要的任何内容)喜欢)。

执行systemd.service此脚本,以便您可以将生成的文件与在 shell 中使用 执行相同脚本时生成的文件进行比较sudo。这两个文件之间的差异将告诉您systemd.

这是一个不太可能的事情,如果它有效的话我会感到惊讶,但是您可以尝试创建一个文件Vars(或您想要给它的任何名称),该文件仅列出变量(每行一个,格式与输出的方式完全相同printenv)存在sudo但不存在systemd,然后将文件Environment=PATH=...中的行更改.serviceEnvironmentFile=/path/to/Vars,然后使用 重新启动服务sudo systemctl daemon-reload

FWIW,当用户尝试使用 Cyber​​ghost 自动化时cron,我发现另一处提到了完全相同的 Python 错误,他能够以一种我不确定我理解也不能保证的方式工作,但也许你会有更好的运气:

https://forum.ubuntu-fr.org/viewtopic.php?id=2060369(法语)

英文翻译

相关内容