我在服务声明中使用它:
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[@]}\""
所以,引用规则:
- 将要视为单个参数的字符串用单引号 ('') 或双引号 (” “)。它们的待遇是一样的,无论您选择哪一个,只要收盘价与开盘价相同即可
- 从左到右扫描字符串,替换'和\',”和\"和$和$$
如果您希望 systemd 进行变量替换,则不要引用$,但 systemd 不处理$var和${var}一样。它们都被环境值取代变量,但是每种情况下分词都会有所不同:$var,替换后的值变量,单词将在空格上分割,而${var}不会出现分词的情况。实际上,systemd 处理$var就像 POSIX shell 会做的那样,但它处理${var}作为 POSIX shell 的处理方式“$var”。