【问题标题】:ExecStart bash script fails; However, running it manually worksExecStart bash 脚本失败;但是,手动运行它可以工作
【发布时间】:2022-01-06 01:23:02
【问题描述】:

我需要 bash 和 systemctl 服务方面的帮助...

我的问题是我的公司要求我自动启动在我们的 KVM 服务器 (CentOS) 上运行的所有虚拟机,我们总共有 5 台物理主机;但是,我在其中一个上遇到了一个问题,我最近更新了我的 VM 版本,我的服务 位于 /etc/systemd/system 下没有运行我的 ExecStart=/bin/bash -c './vmx.sh -lv --start --cfg config/pod8/vmx1.conf' bash 脚本。

file: vmx.service
[Unit]
Description=Juniper vMX Router
Wants=network-online.target
After=network-online.target
After=libvirtd.service

[Service]
WorkingDirectory=/home/vMX-21.1R1/
Environment="PATH=/opt/rh/python27/root/usr/bin:/usr/lib64/qt3.3/bin:/usr/local/sbin:/usr/local/bin:/$

Type=oneshot
User=root
Group=root
RemainAfterExit=true

## Commands used to stop/start/restart the vMX
ExecStart=/bin/bash -c './path-python.sh'

ExecStart=/bin/bash -c './vmx.sh -lv --start --cfg config/pod8/vmx1.conf' <<<<<<<<<<<<<<<<<<<<<<<
ExecStart=/bin/bash -c './vmx.sh -lv --start --cfg config/pod8/vmx2.conf'
ExecStart=/bin/bash -c './vmx.sh -lv --start --cfg config/pod8/vr-device.conf'

[Install]
WantedBy=multi-user.target

这是我的服务状态:

   Loaded: loaded (/etc/systemd/system/vmx.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Mon 2021-11-29 14:04:37 AEST; 2h 4min ago
  Process: 2324 ExecStart=/bin/bash -c ./vmx.sh -lv --start --cfg config/pod8/vmx1.conf (code=exited, status=2)
  Process: 1877 ExecStart=/bin/bash -c ./path-python.sh (code=exited, status=0/SUCCESS)
 Main PID: 2324 (code=exited, status=2)

Nov 29 14:04:37 Juniper-KVM3 bash[2324]: import netifaces as ni
Nov 29 14:04:37 Juniper-KVM3 bash[2324]: ImportError: No module named netifaces
Nov 29 14:04:37 Juniper-KVM3 bash[2324]: Log file........................................../home....log
Nov 29 14:04:37 Juniper-KVM3 bash[2324]: ==================================================
Nov 29 14:04:37 Juniper-KVM3 bash[2324]:  Aborted!. 1 error(s) and 0 warning(s)
Nov 29 14:04:37 Juniper-KVM3 bash[2324]: ==================================================
Nov 29 14:04:37 Juniper-KVM3 systemd[1]: vmx.service: main process exited, code=exited, status=2...MENT
Nov 29 14:04:37 Juniper-KVM3 systemd[1]: Failed to start Juniper vMX Router.
Nov 29 14:04:37 Juniper-KVM3 systemd[1]: Unit vmx.service entered failed state.
Nov 29 14:04:37 Juniper-KVM3 systemd[1]: vmx.service failed.

我认为错误:ImportError: No module named netifaces 将通过运行来修复 pip uninstall netifaces &amp;&amp; pip install netifaces 读入this article。 但是,它也不起作用,无论如何,最奇怪的是,当我在终端中运行相同的脚本时,它起作用了

[root@system]# ./vmx.sh -lv --stop --cfg config/pod8/vmx1.conf
[...]
==================================================
    VMX Status Verification Completed.
==================================================
Log file........................................../home/vMX-21.1R1/build/8m1/logs/vmx_1638166233.log
==================================================
    Thank you for using VMX
==================================================

我确保 SElinux 被禁用:

SELinux status:                 disabled

值得注意的是./path-python.sh脚本运行没有问题,这个脚本可以让我改变我的python27路径,否则我的VM安装会失败,但我可以肯定地说这个问题与 python 本身无关,因为该脚本仅在我在终端中运行时才有效。 (我的其他服务器使用相同的脚本和 bash 按预期工作,我不知道出了什么问题)。

【问题讨论】:

  • 我怀疑你的脚本在网络服务之前启动,所以它没有找到任何 netifaces。但是当计算机启动时,网络正在运行,并且您手动运行脚本时,netifaces 就在那里。

标签: python bash


【解决方案1】:

所以,在玩了virtualenv 之后,我终于成功了!以前运行./vmx.sh脚本时,需要系统使用Python2.7;但是,每次我的主机重新启动时,如果我想完全自动启动所有虚拟机,我需要通过在终端上手动运行以下命令来更改 Python 的 PATH:

echo 'export PATH=/opt/rh/python27/root/usr/bin:$PATH' >> /etc/profile
PATH=/opt/rh/python27/root/usr/bin:$PATH
export PATH
cd /opt/rh/python27/ && . enable && pip install netifaces pyyaml 

而不是从 .sh 脚本运行以前的命令,这最终对我不起作用,有人指出“与 Python 相关的路径调整,将不适用于后续的 ExecStart 命令”。出于这个原因,我做了以下事情:

  1. 我决定通过在 /etc/profile.d/ 下创建一个脚本来保留更改,而不是运行 scl enable python27 bash(这将使我的 Python 版本成为默认值,直到您注销)
#!/bin/bash
source scl_source enable python27
  1. 我安装了 virtualenv pip install virtualenv

  2. 创建了一个虚拟环境virtualenv --python=/usr/bin/python2.7 vMX-ENV,我将使用它来安装我的所有包和脚本来安装我的虚拟机

  3. 激活了我的虚拟环境source /home/vMX-ENV/bin/activate

  4. 创建了 ./vmx.sh 脚本所在的目录 (vMX-*)。

# ls
bin  lib  lib64  pyvenv.cfg  vMX-21.1R1 
  1. 在该目录中,我创建了一个 bash 脚本,该脚本将在启动时由服务启动,我将其命名为:pyrun.sh,此脚本运行 ./vmx。 sh 脚本“信用:AKX
#!/bin/bash

source /home/vMX-ENV/bin/activate
./vmx.sh -lv --start --cfg config/pod17/vmx1.conf
# ...
  1. 创建了 vmxd.serviceExecStart=/bin/bash -c './pyrun.sh'

通过创建 virtualenv,我能够隔离我的 Python 项目,方法是只创建一个包含所有需要的包的独特环境并只运行运行 ./vmx.sh 所需的 Python2.7

重启主机后,journalctl -u vmxd.service 成功输出如下:

Starting Juniper vMX Router...
==================================================
Welcome to VMX
==================================================
[...]

【讨论】:

    【解决方案2】:

    ExecStart 命令是单独运行的,而不是在同一个 shell 中。

    换句话说,如果

    ExecStart=/bin/bash -c './path-python.sh'
    

    设置一些与 Python 相关的路径调整,它们将不适用于后续的 ExecStart 命令。

    而不是“更改您的 python27 路径”的脚本,我建议您为该 Python 环境设置一个 virtualenv,并在其中安装您需要的软件包,这样您就可以在您的 vmx.sh 中使用该 virtualenv 的解释器。如果你不能编辑vmx.sh,你可以设置一个脚本来做类似的事情

    #!/bin/bash
    
    source /opt/myvirtualenv/bin/activate
    ./vmx.sh -lv --start --cfg config/pod8/vmx1.conf
    # ...
    

    然后运行它; activate 脚本确保 virtualenv 的 Python 是该 shell 会话的主要 Python。

    【讨论】:

    • 感谢您的评论,我终于根据您的回答解决了问题。我已经更详细地解释了答案,但简而言之,解决方案是通过在 virtualenv 上运行脚本来隔离 python 环境,它可以完美运行!
    猜你喜欢
    • 2013-01-14
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多