systemctl服务执行bash中正常的反引号命令时传参错误如何解决
问题原因
systemd的ExecStart、ExecStartPre等指令默认不会调用shell解析命令,因此bash中的命令替换(反引号`或$()语法)、管道、通配符等特性都无法直接生效,你写的反引号内容会被当做普通字符串直接传递给docker命令,才会出现参数解析异常的报错。
解决方案
方案1:显式通过bash执行命令
直接修改ExecStart配置,将完整命令用bash -c包裹,注意内部引号的适配,修改后的Service段配置如下:
[Service] Restart=always ExecStartPre=-/usr/bin/docker stop java_redis ExecStartPre=-/usr/bin/docker rm java_redis ExecStart=/bin/bash -c "/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
说明:这里把反引号替换成了
$()写法,避免和外层引号产生冲突,执行效果和反引号完全一致。
方案2:封装为独立shell脚本(更易维护)
如果后续命令还会调整,建议把启动逻辑单独写成shell脚本,比如创建/opt/start_java_redis.sh,内容如下:
#!/bin/bash /usr/bin/docker stop java_redis || true /usr/bin/docker rm java_redis || true redis_host=$(docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge) /usr/bin/docker run --name java_redis --rm java_redis:latest --redis_host "${redis_host}"
给脚本加执行权限:chmod +x /opt/start_java_redis.sh
之后修改服务配置的ExecStart即可:
[Service] Restart=always ExecStart=/opt/start_java_redis.sh ExecStop=/usr/bin/docker stop -t 2 java_redis
修改配置后需要执行systemctl daemon-reload重新加载服务配置,再启动服务即可正常运行。
内容的提问来源于stack exchange,提问作者user565447
相关产品推荐
相关产品推荐

