Systemctl 没有在 bash 中完美执行的 运行 命令(反引号)
Systemctl doesn't run command which is perfectly executed in bash (back quote)
问题是执行命令的结果没有正确传递到 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
阅读 ExecStart=
leads me to Command Lines 的文档,其中指定仅支持简单的参数解析,解决此问题的一种方法是将整个命令行包装在 shell:
中
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 ...)"'
问题是执行命令的结果没有正确传递到 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
阅读 ExecStart=
leads me to Command Lines 的文档,其中指定仅支持简单的参数解析,解决此问题的一种方法是将整个命令行包装在 shell:
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 ...)"'