docker-compose entrypoint标签中单引号转义失效问题求助
Docker Compose Entrypoint 单引号转义失效问题解决
问题场景
在Docker Compose的entrypoint配置中尝试转义单引号,该操作在命令行中有效,但yaml配置里却失效,导致输出的SQL语句丢失了单引号。
示例配置(test.yml)
version: "2.4" services: mysql: container_name: test image: "java-build:21-focal" entrypoint: /bin/bash -c " echo $'CREATE DATABASE IF NOT EXISTS temporal; CREATE DATABASE IF NOT EXISTS temporal_visibility; GRANT ALL PRIVILEGES ON *.* TO \'temporal_admin\'@\'%\'; GRANT ALL PRIVILEGES ON *.* TO \'temporal_admin\'@\'%\'; FLUSH PRIVILEGES;' > /tmp/init.sql; cat /tmp/init.sql "
实际输出
CREATE DATABASE IF NOT EXISTS temporal; CREATE DATABASE IF NOT EXISTS temporal_visibility; GRANT ALL PRIVILEGES ON *.* TO temporal_admin@%; GRANT ALL PRIVILEGES ON *.* TO temporal_admin@%; FLUSH PRIVILEGES;
解决思路
1. 改用数组形式定义Entrypoint(推荐)
将entrypoint拆分为数组参数,避免YAML解析与Bash解析的转义冲突,同时使用YAML块折叠语法(|)提升可读性,Bash内转义单引号采用'\''格式:
version: "2.4" services: mysql: container_name: test image: "java-build:21-focal" entrypoint: - /bin/bash - -c - | echo 'CREATE DATABASE IF NOT EXISTS temporal; CREATE DATABASE IF NOT EXISTS temporal_visibility; GRANT ALL PRIVILEGES ON *.* TO '\''temporal_admin'\''@'\''%'\''; GRANT ALL PRIVILEGES ON *.* TO '\''temporal_admin'\''@'\''%'\''; FLUSH PRIVILEGES;' > /tmp/init.sql; cat /tmp/init.sql
原理:数组形式会将每个参数原封不动传递给Bash,'\''的作用是临时关闭单引号、输出一个单引号、再重新打开单引号,确保Bash能正确识别SQL中的单引号。
2. 利用YAML单引号包裹命令
YAML中单引号内的内容不会被解析转义,内部单引号需用两个单引号转义(YAML语法规则):
version: "2.4" services: mysql: container_name: test image: "java-build:21-focal" entrypoint: '/bin/bash -c "echo ''CREATE DATABASE IF NOT EXISTS temporal; CREATE DATABASE IF NOT EXISTS temporal_visibility; GRANT ALL PRIVILEGES ON *.* TO ''''temporal_admin''''@''''%''''; GRANT ALL PRIVILEGES ON *.* TO ''''temporal_admin''''@''''%''''; FLUSH PRIVILEGES;'' > /tmp/init.sql; cat /tmp/init.sql"'
注意:此方式可读性较差,仅适合短命令场景。
3. 挂载独立SQL文件(最优雅)
如果是数据库初始化场景,建议将SQL语句单独写入文件,通过volumes挂载到容器的初始化目录(如MySQL的/docker-entrypoint-initdb.d/),彻底规避引号转义问题:
- 新建
init.sql文件:
CREATE DATABASE IF NOT EXISTS temporal; CREATE DATABASE IF NOT EXISTS temporal_visibility; GRANT ALL PRIVILEGES ON *.* TO 'temporal_admin'@'%'; GRANT ALL PRIVILEGES ON *.* TO 'temporal_admin'@'%'; FLUSH PRIVILEGES;
- 修改Docker Compose配置:
version: "2.4" services: mysql: container_name: test image: "java-build:21-focal" volumes: - ./init.sql:/docker-entrypoint-initdb.d/init.sql
失效原因分析
原配置中存在两层解析冲突:
- YAML解析时,会将
\'视为转义单引号并自动去除转义符,导致传递给Bash的内容已经丢失了单引号; $'...'的写法在YAML中可能被解析为变量引用,进一步破坏了转义逻辑。
内容的提问来源于stack exchange,提问作者nar007
相关产品推荐
相关产品推荐

