如何从主机执行MySQL命令到运行MySQL服务器的容器?

80

我按照https://registry.hub.docker.com/_/mysql/中的指示拉取了一个镜像,并在其中运行了一个MySQL服务器的容器。

该容器正在后台运行,我想运行一些命令。

最好的方法是如何连接到容器并从命令行执行此命令?

谢谢。

10个回答

112

您可以使用以下命令连接到您的mysql容器并运行您的命令:

docker exec -it mysql bash -l

(其中mysql是您给容器命名的名称)

请记住,您所做的任何更改都不会持久保存到下次从相同映像运行容器时。


2
RPC错误:代码=2说明=OCI运行时错误:执行失败:container_linux.go:247:启动容器进程导致“exec:"-it":在$PATH中找不到可执行文件”,使用您的解决方案出现此错误。 - Madhavi Jouhari
为什么说任何操作都不会持久存在?这取决于其他参数(主要是实际数据库数据的位置——它是否使用卷挂载到主机上?)和与docker exec无关。 - eyalzba
@eyalzba,他在docker命令中没有挂载任何内容。如果他添加了-v ./mysql:/var/lib/mysql或类似的内容,它将会持久化 - 但他没有这样做。请记住,这是使用普通的docker,而不是docker-compose(所以你看到的就是所有已定义的内容)。 :) - XtraSimplicity
@XtraSimplicity,你说的和我说的完全一样。我只是补充说我不知道他是用“-v”还是没有运行。 - eyalzba
这个命令完美运行:docker exec -it {{CONTAINER ID}} mysql -u {{USERNAME}} -p {{PASSWORD}}。 - Amit Dwivedi

54
docker exec -i some_mysql_container mysql -uroot -ppassword  <<< "select database();"

4
<<<是一个Shell输入重定向符号,它将后面的内容作为标准输入提供给前面的命令。三个小于号表示将后面的内容视为“Here String”,它可以方便地将一个字符串作为输入传递给命令。为什么使用三个而不是两个,则是因为这是Bash Shell中规定的语法。 - vladkras
9
“<<<”指示 shell 将其后面的内容视为标准输入(stdin),类似于从 echo 进行管道传递。 - Ayushya
非常感谢。我正在研究如何创建一个别名,以便在只输入一个命令后登录到mysql,而这个答案帮助了我。正如@Andreas Volkmann所解释的那样,我必须在执行查询之前使用“-e”选项。在我的情况下,“<<<”选项不起作用。 - James Selvakumar
@JamesSelvakumar,“<<<”对我也没有用。我使用了“-e”参数来运行查询。 - nonethewiser
这个答案对我非常有用。我想从一个bash脚本中运行一些设置命令,以便为一个新的mysql docker实例进行设置。完美的解决方案! - Joel Gray

41

使用MySQL命令行客户端连接到MySQL数据库

  1. 通过bash进入正在运行的MySQL容器:

    $ docker exec -t -i container_mysql_name /bin/bash

    -i--interactive 选项的快捷方式。该选项用于保持标准输入开启,即使没有附加。

    -t--tty 选项的快捷方式,用于分配伪终端。

  2. 从bash MySQL容器中运行MySQL客户端:

    $ mysql -uroot -proot

    -u--user=name 选项的快捷方式,用于定义登录用户(如果不是当前用户)。

    -p-password[=name] 选项的快捷方式,用于定义连接到服务器时要使用的密码。如果未提供密码,则会从tty上询问。

  3. 尽情跳舞吧!


13
您可以将这些步骤组合起来,像这样:docker exec -t -i container_mysql_name /bin/bash -c "mysql -uroot -proot" - ocarlsen

25

在我的情况下,<<< 解决方案无法工作。

相反,我使用了 -e

示例:

docker exec ${CONTAINER_NAME} mysql -u ${USER_NAME} -p${PASSWORD} -e "drop schema test; create schema test;"


1
我试图创建一个别名,以便在一个命令中登录到mysql,而这个特定的解决方案帮助了我。非常感谢。 - James Selvakumar
2
你如何运行一个 .sql 文件而不是执行硬编码的 SQL 查询呢? - Parag Kadam
1
@ParagKadam,您可以按照以下方式操作:docker exec -i mySqlContainer mysql -uroot -pmypassword < file.sql(也许现在有点晚了,但对其他人可能有所帮助)。 - Dwhitz

25

对于@Abdullah Jibaly的解决方案,在测试了MySQL 5.7后,它只会进入bash终端提示,您仍然需要再次输入mysql命令。

为了在使用一行命令运行MySQL容器后直接进入MySQL命令行客户端,请运行以下命令:

docker exec -it container_mysql_name mysql -u username -p

3
通过使用docker run,可以启动一个新的容器来执行您的mysql语句。当您尝试使用本地主机连接到mysql时运行语句并遇到访问被拒绝问题时,这种方法有助于解决该问题。
$ docker run -it --rm mysql mysql -h172.17.0.2 -uroot -pmy-secret-pw -e "show databases;"

我不相信这会起作用,因为mysql...命令会覆盖图像的默认命令mysqld。因此,容器中不会运行mysql,无法响应连接。 - undefined

2

我使用以下命令来解决容器内外数据库的一些情况(使用-h-P)并支持-e

最初的回答:

cat > ~/bin/mysql <<'EOF'
#/bin/bash

MARGS=()
MPORT="3306"

while test $# != 0; do
  if [[ $1 == -h ]]; then MHOST=$2; shift;
  elif [[ $1 == -h* ]]; then MHOST=${1#"-h"};
  elif [[ $1 == -e ]]; then MEXEC=$2; shift;
  elif [[ $1 == -e* ]]; then MEXEC=${1#"-e"};
  elif [[ $1 == --execute=* ]]; then MEXEC=${1#"--execute="};
  elif [[ $1 == -P ]]; then MPORT=$2; shift;
  elif [[ $1 == -P* ]]; then MPORT=${1#"-P"};
  else MARGS="$MARGS $1"
  fi

  shift;
done

if [ -z  "${MHOST+x}" ]; then
   MHOST=localhost
fi

if [ $(docker inspect --format '{{ .State.Status }}' mysql) == "running" ]; then
 if [ ! -z "${MHOST+x}" ]; then
    if [ "$MHOST" == "localhost" -o "$MHOST" == "127.0.0.1" ]; then
      CPORT=$(docker port mysql 3306/tcp)
      if [ ${CPORT#"0.0.0.0:"} == $MPORT ]; then
        #echo "aiming for container port ($MPORT -> $CPORT)";
        MHOST=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mysql);
      else
        MHOST=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | head -1);
      fi
    fi
  fi
fi

if [ -z "$MEXEC" ]; then
   docker run --link mysql:mysql -i --rm mysql mysql "-h" $MHOST "-P" $MPORT $MARGS
else
   docker run --link mysql:mysql -i --rm mysql mysql "-h" $MHOST "-P" $MPORT $MARGS <<< $MEXEC
fi
EOF
chmod +x ~/bin/mysql

2
我发现这些解决方案对我的使用情况并不有效:需要将从SQL返回的数据存储到bash变量中。
当我在主机计算机上运行的bash脚本(在docker mysql服务器之外)中进行调用时,最终采用了以下语法,基本上使用'echo'将SQL语句转发到docker exec命令的stdin。
根据您的使用情况修改以下内容以指定mysql容器名称和正确的mysql用户和密码:
#!/bin/bash
mysqlCMD="docker exec -i _mysql-container-name_ mysql -uroot -proot "
sqlCMD="select count(*) from DBnames where name = 'sampleDB'"
count=`echo $sqlCMD | $mysqlCMD | grep -v count`

# count variable now contains the result of the SQL statement

由于某种原因,当我使用-e选项,并在反引号中提供该字符串时,解释器修改了引号,导致SQL语法失败。

Richard


0
我使用了以下命令。但在您的图像定义在docker-compose文件中的情况下。
sudo docker compose exec -it companydb mysql -u company -p company
companydb:这个服务拉取的mysql镜像,也被标识为容器名称。

0
创建一个MySQL Docker容器镜像:
命令:
docker run --name <cotainer-name> -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

使用-e选项来设置Docker容器镜像的环境变量。
如果您不确定要使用哪个mysql镜像标签,请使用mysql:latest在Docker容器镜像上通过MySQL客户端运行MySQL查询: 命令:
1. docker exec -it <cotainer-name> bash -l
2. mysql -n<username> -p<password>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接