如何在 systemd 中使用报价和美元符号

如何在 systemd 中使用报价和美元符号

我在服务声明中使用它:

ExecStartPre=/usr/bin/docker pull "$DOCKER_USERNAME/redis-replication:latest"

在 systemd 的日志中,当我尝试启动服务时可以看到以下内容:

Usage: docker pull [OPTIONS] NAME[:TAG]
Pull an image or a repository from the registry
-a, --all-tags=false    Download all tagged images in the repository

看起来 systemd 没有执行正确的命令,而是执行了一些奇怪的命令。可能是什么以及如何纠正?

已编辑:这是我的整个单元文件

[Unit]
Description=Run redis replication
After=docker.service
Requires=docker.service

[Service]
Restart=always
RestartSec=10s
EnvironmentFile=/etc/vax/credentials
EnvironmentFile=/etc/vax/centos-ip
EnvironmentFile=/etc/vax/docker-auth
EnvironmentFile=/etc/vax/cluster-prefix
ExecStartPre=-/usr/bin/docker kill redisrep
ExecStartPre=-/usr/bin/docker rm redisrep
ExecStartPre=/usr/bin/docker pull "$DOCKER_USERNAME/redis-replication:latest"
ExecStart=/usr/bin/docker run --rm --name redisrep    -v /var/data/myproject/redis:/data    -e S3_ACCESS_KEY=$S3_ACCESS_KEY    -e S3_SECRET_KEY=$S3_SECRET_KEY    -e S3_BUCKET=$S3_BUCKET    -e BACKUP_PREFIX=$BACKUP_PREFIX    -e REPLICATE_FROM_IP=$CENTOS_IP    -e REPLICATE_FROM_PORT=6379    $DOCKER_USERNAME/redis-replication:latest
ExecStop=/usr/bin/docker kill redisrep

[X-Fleet]
MachineMetadata="machineIndex=1"

答案1

经过一番研究,我发现在 systemd 服务文件的 ExecStart 定义中使用引号是可以的。至于使用 shell 变量,当非空格字符连接到变量本身时,需要使用花括号来明确变量名的结束位置。

在上述情况下,系统必须将视为$DOCKER_USERNAME/redis变量名而不是$DOCKER_USERNAME。添加大括号即可正确解释。

编辑:有关 systemd 可以使用的语法的更多信息可以在这里找到:http://www.freedesktop.org/software/systemd/man/systemd.service.html#Command%20lines

基本上大多数 shell 表示法都可以,除了管道运算符。

答案2

ExecStart我只是努力在服务单元文件的键中引用并运行以下命令行:

IFS=$'\n'; f=($(ls $HOME/bk.d/DuckieTV*.backup | tail -n +2)); echo "${f[@]}"

我将使用 systemd 引用规则来引用它,然后我将解释我在这个过程中学到的东西。它看起来很复杂,因为我们希望它遵循 POSIX shell 的引用规则,但实际上它更简单。这是ExecStart正确引用的指令

ExecStart=/bin/bash -c 'IFS=$$\'\\n\'; f=($$(ls ${HOME}/bk.d/DuckieTV*.backup | tail -n +2)); echo \"$${f[@]}\"'

或者

ExecStart=/bin/bash -c "IFS=$$\'\\n\'; f=($$(ls ${HOME}/bk.d/DuckieTV*.backup | tail -n +2)); echo \"$${f[@]}\""

所以,引用规则:

  1. 将要视为单个参数的字符串用单引号 ('') 或双引号 (” “)。它们的待遇是一样的,无论您选择哪一个,只要收盘价与开盘价相同即可
  2. 从左到右扫描字符串,替换'\',\"$$$

如果您希望 systemd 进行变量替换,则不要引用$,但 systemd 不处理$var${var}一样。它们都被环境值取代变量,但是每种情况下分词都会有所不同:$var,替换后的值变量,单词将在空格上分割,而${var}不会出现分词的情况。实际上,systemd 处理$var就像 POSIX shell 会做的那样,但它处理${var}作为 POSIX shell 的处理方式“$var”

相关内容