为什么这个 systemd 单元文件不起作用?

为什么这个 systemd 单元文件不起作用?

最初我在 Ubuntu 上运行了这个脚本,基本上是放入 rc.local 中

#!/bin/bash

IBSYSDIR="/home/matthewh/tmp"
hca_id=1
if [ -d ${IBSYSDIR} ]; then
  for hca in ${IBSYSDIR}/*; do
    if [ -e ${hca}/node_desc ]; then
      echo -n "$(hostname -s) HCA-${hca_id}" >> ${hca}/node_desc
    fi
    hca_id=$((hca_id+1))
  done
fi

现在我的基础设施是 CoreOS,我想恢复此脚本来设置所有节点的 Infiniband 主机名。

理想情况下,为了节省管理开销,我只想将单个服务文件放入 cloud-init 一次并启动它。所以我想出了下面显示的 systemd 服务文件。在想出单个文件奇迹的过程中,我设法将原始文件脚本中的命令缩短为一行。

[ -d ${IBSYSDIR} ] && for hca in ${IBSYSDIR}/*; do [ -e ${hca}/node_desc ] && echo -n "$(hostname -s) HCA-${hca_id}" >> ${hca}/node_desc; done

然而,我似乎无法运行/bin/sh -c "[ -d ${IBSYSDIR} ] && for hca in ${IBSYSDIR}/*; do [ -e ${hca}/node_desc ] && echo -n "$(hostname -s) HCA-${hca_id}" >> ${hca}/node_desc; done"

也许它没有正确地将环境拉入 sh。如何让它仅在单个服务文件(没有其他依赖脚本)内工作?

服务文件和实际错误如下。

[Unit]
Description=Set the infiniband hostname

[Service]
Type=oneshot
Environment="IBSYSDIR=/sys/class/infiniband"
Environment="hca_id=1"
ExecStart=/bin/bash -c "[ -d ${IBSYSDIR} ] && for hca in ${IBSYSDIR}/*; do [ -e ${hca}/node_desc ] && echo -n "$(hostname -s) HCA-${hca_id}" >> ${hca}/node_desc; done"

[Install]
WantedBy=multi-user.target

我看到的实际错误:

Sep 10 00:30:21 service2-2 systemd[1]: Starting Set the infiniband hostname...
Sep 10 00:30:21 service2-2 sh[11134]: -s): -c: line 0: unexpected EOF while looking for matching `)'
Sep 10 00:30:21 service2-2 sh[11134]: -s): -c: line 1: syntax error: unexpected end of file

所以我做了一些进一步的努力,但仍然不起作用。

[Unit]
Description=Set the infiniband hostname
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'IBSYSDIR=/sys/class/infiniband && hca_id=1 && [ -d ${IBSYSDIR} ] && for hca in ${IBSYSDIR}/*; do [ -e ${hca}/node_desc ] && echo -n "$(hostname -s) HCA-${hca_id}" >> "${hca}/node_desc"; done'

[Install]
WantedBy=multi-user.target

但如果我直接运行

sudo /bin/bash -c 'IBSYSDIR=/sys/class/infiniband && hca_id=1 && [ -d ${IBSYSDIR} ] && for hca in ${IBSYSDIR}/*; do [ -e ${hca}/node_desc ] && echo -n "$(hostname -s) HCA-${hca_id}" >> "${hca}/node_desc"; done'

它确实有效。服务文件有什么特别之处?返回的错误代码是 1。我猜这是权限被拒绝的错误或其他什么。

答案1

$将所有 改为$$

来自 systemd.unit 文档:

要传递文字美元符号,请使用“$$”。在扩展时未知值的变量将被视为空字符串。请注意,第一个参数(即要执行的程序)可能不是变量。

答案2

根据我的经验,systemd 不喜欢在其ExecStart指令中包含复杂的命令。

尝试将您的脚本放入包装文件中并从中运行该脚本ExecStart

相关内容