首页 > 解决方案 > 如何在 docker-compose 入口点中转义'

问题描述

我想用它在 docker-compose up -d 上创建数据库和初始化用户

entrypoint:
  sh -c "
    echo 'CREATE DATABASE IF NOT EXISTS firstDB;CREATE DATABASE IF NOT EXISTS secondDB;' > /docker-entrypoint-initdb.d/init.sql;
    /usr/local/bin/docker-entrypoint.sh --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
  "

这工作得很好,但这是问题所在

sh -c "echo 'CREATE DATABASE IF NOT EXISTS firstDB;CREATE DATABASE IF NOT EXISTS secondDB;GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;' > /docker-entrypoint-initdb.d/init.sql;
    /usr/local/bin/docker-entrypoint.sh --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
  "

我试图用 '' 或 \' 逃避 ' .... 没有任何效果。

任何帮助请如何逃脱'?

谢谢

标签: dockerdocker-compose

解决方案


对于此用例,您不需要这样做。创建一个init.sql包含该字符串的本地文件;因为它只是一个文件,所以您根本不需要进行任何 shell 转义。使用volumes:声明将文件挂载到容器中,并使用图像的默认入口点。例如:

version: '3'
services:
  mysql:
    image: 'mysql:8'
    volumes:
      - 'mysql:/var/lib/mysql'
      - './init.sql:/docker-entrypoint-initdb.d/init.sql' # <-- this
    ports:
      - '5432:5432'
volumes:
  mysql:

如果您有多个文件,则可以将它们放在共享目录中并将整个目录挂载到容器中。如果您需要像您展示的特殊选项,您可以将这些选项(仅)作为command:

command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

如果您确实需要将其作为复杂的脚本执行,我建议将其写入 shell 脚本,而不是尝试内联;它节省了一级引用,您可以使用 heredocs 之类的 shell 功能来进一步简化它。我可能会将其构建到自定义映像中,但您可以以与上述相同的方式将其安装到容器中。

如果一切都失败了,您可以尝试在本地 shell 中运行该命令,但将其放在echo它前面,或者从sh -c包装器中删除第二个命令。这将在 shell 完成所有引用和其他扩展后打印出命令行,以便您更清楚地了解写出的内容。

echo sh -c "echo 'CREATE DATABASE ...'"

(如果您需要在带引号的字符串中的带引号的字符串中写出文字引号,这很讨厌。我可能尝试的一种变体是将echo参数用双引号括起来,因为它们在双引号字符串中,所以需要转义

sh -c "echo \"CREATE ... 'root'%'@' ...\" > /docker-entrypoint-initdb.d/init.sql"

推荐阅读