【问题标题】:Systemctl doesn't run command which is perfectly executed in bash (back quote)Systemctl 不运行在 bash 中完美执行的命令(反引号)
【发布时间】:2021-11-28 11:44:28
【问题描述】:

问题是执行命令的结果没有正确传递到systemctl服务中,而在bash中执行这样的命令是正确的。

这是我的服务:

[Unit]
Description=Java jar which listens to Redis
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStartPre=-/usr/bin/docker stop java_redis
ExecStartPre=-/usr/bin/docker rm java_redis
ExecStart=/usr/bin/docker run --name java_redis --rm java_redis:latest --redis_host `docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge`
ExecStop=/usr/bin/docker stop -t 2 java_redis

[Install]
WantedBy=multi-user.target

如果我在 bash 中运行,则执行以下命令时不会出错:

/usr/bin/docker run --name java_redis --rm java_redis:latest --redis_host `docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge`

当我在 journal 中搜索时,我注意到参数没有正确传递:

Oct 08 21:04:55 mscphisprk00034 docker[1328378]: No argument is allowed: network
Oct 08 21:04:55 mscphisprk00034 docker[1328378]: org.kohsuke.args4j.CmdLineException: No argument is allowed: network
Oct 08 21:04:55 mscphisprk00034 docker[1328378]:         at org.kohsuke.args4j.CmdLineParser.parseArgument(CmdLineParser.java:509)

您能告诉我如何在 systemctl 服务中获取该参数吗?

我需要传递一个参数,该参数是以下命令的结果:

docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge

【问题讨论】:

  • 这似乎不是一个与编程相关的问题;像Unix & Linux 这样的网站可能是询问 systemctl 单元文件的更好地方。一般来说,Docker 内部 IP 地址并不意味着可用(并且在非 Linux 平台上无法访问),我会避免您显示的那种 docker inspect 查找;你应该能够连接到localhostdocker run -p ???:6379 端口号。

标签: bash docker systemctl


【解决方案1】:

阅读ExecStart= 的文档将我带到Command Lines,它指定仅支持简单的参数解析,解决此问题的一种方法是将整个命令行包装在外壳中:

ExecStart=/bin/sh -c '/usr/bin/docker run --name java_redis --rm java_redis:latest --redis_host "$(/usr/bin/docker network inspect --format="{{range .IPAM.Config}}{{.Gateway}}{{end}}" bridge)"'

请注意我如何将内部单引号更改为双引号以避免解析器混淆。

为了更好地衡量,与您对docker 的引用保持一致是有意义的,要么将其写为完整路径,要么不写。只是避免混合使用这两个引用,例如使用/usr/bin/docker 或使用docker

通常也最好使用$(...) 而不是老式的`…`

ExecStart=/bin/sh -c '/usr/bin/docker run ... --redis_host $(/usr/bin/docker network ...)'

并记得引用扩展名以避免它经历分词和路径名扩展:

ExecStart=/bin/sh -c '/usr/bin/docker run ... --redis_host "$(/usr/bin/docker network ...)"'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 2013-07-20
    • 2017-07-10
    • 2014-11-22
    • 2011-04-19
    • 1970-01-01
    相关资源
    最近更新 更多