【问题标题】:Check if mysql database exists, perform action based on result检查mysql数据库是否存在,根据结果执行操作
【发布时间】:2023-03-07 14:39:02
【问题描述】:

是否可以在 bash 脚本中检查 mysql 数据库是否存在。然后根据结果执行另一个操作或终止脚本?

【问题讨论】:

    标签: mysql linux bash


    【解决方案1】:

    mysql 命令中使用-e 选项。它会让你执行任何查询(假设有正确的凭据)。

    这可能是一个例子:

    if mysql "DATABASE_NAME" -e exit > /dev/null 2>&1; then
        echo "Exists"
    else
        echo "Not exists"
    fi
    

    【讨论】:

      【解决方案2】:

      这是我在 bash 脚本中的操作方式:

      #!/bin/sh
      
      DATABASE_USER=*****
      DATABASE_PWD=*****
      DATABASE_NAME=my_database
      
      if mysql -u$DATABASE_USER -p$DATABASE_PWD -e "use $DATABASE_NAME";
      then
      echo "Database $DATABASE_NAME already exists. Exiting."
      exit
      else
      echo Create database
      mysql -u$DATABASE_USER -p$DATABASE_PWD -e "CREATE DATABASE $DATABASE_NAME"
      fi
      

      【讨论】:

        【解决方案3】:

        mysqlshow是一个很好的工具,这里是测试数据库database_name是否存在

        if mysqlshow -p${MYSQL_ROOT} 2>/dev/null| grep -q "database_name"
        then
            echo "Database exist."
        else
            echo "Database does not exist."
        fi
        

        或者一个简单的单线器

        echo "Database "`mysqlshow -p${MYSQL_ROOT} 2>/dev/null| grep -q "database_name"  || echo "does not "`"exist."
        

        【讨论】:

          【解决方案4】:

          您也可以要求使用数据库,然后处理退出代码。

          $ if mysql -uroot -pxxx -e "USE mysql"; then echo "exists"; fi
          exists
          
          $ if mysql -uroot -pxxx -e "USE doesnotexist"; then echo "exists"; fi
          ERROR 1049 (42000) at line 1: Unknown database 'doesnotexist'
          

          或者检查$?通话后。

          【讨论】:

            【解决方案5】:

            我给answer by @chown +1,但这里有另一种选择:如果 bash 脚本与 MySQL 实例一起在本地运行,并且您知道 datadir 的路径,则可以测试:

            if [ -d /var/lib/mysql/databasename ] ; then 
                # Do Stuff ...
            fi
            

            这还假设您运行脚本的 shell 用户具有文件系统级别的权限来读取 MySQL 数据目录的内容。这种情况经常发生,但并不确定。

            【讨论】:

            • 这实际上是一种更简洁的方式,因为文件夹在 information_schema 中注册为数据库。此外,不需要用户身份验证(换句话说,无需登录)。 +1 !!!
            • 这是一个更优雅、更可靠的解决方案。我喜欢它:D
            • 如果我没记错的话,取决于file_per_table。路径取决于操作系统。
            • @scones,不,无论您是否使用 innodb_file_per_table,每个数据库都有一个目录,至少到 MySQL 5.7。无论您的表使用什么存储引擎,该目录下都有元数据文件。我不确定 MySQL 8.0 是否会改变,因为它们改变了 InnoDB 元数据的管理方式。
            • 我知道我真的迟到了,但我只想说,虽然它确实有效,但你必须在 mysql 组或 chmod 754 中。如果不是,权限被拒绝
            【解决方案6】:

            FWIW,auth_socket 插件使这变得更容易。这个问题可能已经很老了,但仍然有像我这样的人来这里寻求灵感。

            如果您的脚本以 root 身份运行,您可以这样做:

            DBNAME="what_you_are_looking_for"
            DBEXISTS="$(mysql -u root -e "show databases like '$DBNAME'" --batch --skip-column-names)"
            

            如果数据库存在,则$DBNAME = $DBEXISTS

            如果数据库不存在,则$DBEXISTS = ""

            两者的退出状态都应为 0,因此您仍然可以使用非零状态来报告错误,而不是让不存在的数据库显示为错误。

            【讨论】:

              【解决方案7】:

              如果有帮助,我在 Debian Stretch 上为 MariaDB 做了这个:

              DB_CHECK=$(mysqlshow "${DB_NAME}" | grep "Unknown database") 1> /dev/null
              if [ ! -z "${DB_CHECK}" ]; then
                  echo "Database found."
              else
                  echo "Database not found."
              fi
              

              简短说明:mysqlshow 变量$DB_NAME 中的数据库名称的结果被检查为“未知数据库”。如果找到该字符串,则将其放入变量$DB_CHECK。然后最后-z 比较检查$DB_CHECK 变量是否为空。

              如果$DB_CHECK 为空,则mysqlshow 响应中不会出现“未知数据库”。可能不是 100% 可靠,例如连接失败或其他情况。 (我没有测试过。)

              【讨论】:

                【解决方案8】:

                这是另一个版本:

                 RESULT=`mysql -u$USER -p$PASSWORD -e "SHOW DATABASES" | grep $DATABASE`
                 if [ "$RESULT" == "$DATABASE" ]; then
                    echo "Database exist"
                 else
                    echo "Database does not exist"
                 fi
                

                如果有一个名为abcd 的数据库,我们在grep 之后使用-Fo,那么对于数据库a/ab/abc 的搜索结果,脚本将显示结果Database exist

                【讨论】:

                • 如果我有 2 个数据库,如 abcdabcd_xyz
                【解决方案9】:

                没有grep的另一种解决方案:

                FOUND_DATABASES=`MYSQL_PWD="${DB_PASSWORD}" mysql \
                 -u "${DB_PASSWORD}" \
                 --skip-column-names \
                 --batch \
                 -e "SHOW DATABASES LIKE '${DB_NAME}'" | wc -l`
                

                FOUND_DATABASES

                • 0 - 没有这样的数据库
                • 1 - 找到数据库

                注意事项:

                • MYSQL_PWD 禁用警告:

                  mysql: [警告] 在命令行界面使用密码可能不安全。

                • --skip-column-names 隐藏列

                • --batch 禁用像+-----------+ 这样的边框

                【讨论】:

                  【解决方案10】:

                  mysqlshow 路径需要解析输出(至少对于我拥有的 mysql 版本),因为它总是返回成功。 Dale 在区分失败方面提出了一个很好的观点。

                  但是,如果您知道一切都在运行并且您拥有正确的凭据等,并且您想告诉数据库是否存在,您就不能这样做一行中有一个空白的 sql 命令:

                  > mysql -uroot -ppassword good_db -e ''
                  > echo $?
                  0
                  > mysql -uroot -ppassword bad_db -e ''
                  ERROR 1049 (42000): Unknown database 'busker_core_locala'
                  > echo $?
                  1
                  

                  【讨论】:

                    【解决方案11】:

                    使用 mysqlshow 很容易可靠地判断数据库是否存在。诀窍是能够可靠地区分数据库存在或其他故障。在任何一种情况下,我的 mysqlshow 版本都以 '1' 退出,所以它无法分辨。

                    这是我想出的处理它的方法。相应地调整您的 mysqlshow 命令,或将您的凭据放入 chmod 600'd ~/.my.cnf 文件中。

                    这适用于 Ubuntu 12 + 14。我还没有在其他环境中测试过:

                    #!/bin/bash -u
                    
                    # Takes 1 argument. Aborts the script if there's a false negative.
                    function mysql_db_exists () {
                      local DBNAME="$1"
                      # Underscores are treated as wildcards by mysqlshow.
                      # Replace them with '\\_'. One of the underscores is consumed by the shell to keep the one mysqlshow needs in tact.
                      ESCAPED_DB_NAME="${DBNAME//_/\\\_}"
                      RESULT="$(mysqlshow "$ESCAPED_DB_NAME" 2>&1)"; EXITCODE=$?
                      if [ "$EXITCODE" -eq 0 ]; then
                        # This is never a false positive.
                        true
                      else
                        if echo "$RESULT" | grep -iq "Unknown database"; then
                          # True negative.
                          false
                        else
                          # False negative: Spit out the error and abort the script.
                          >&2 echo "ERR (mysql_db_exists): $RESULT"
                          exit 1
                        fi
                      fi
                    }
                    
                    if mysql_db_exists "$1"; then
                      echo "It definitely exists."
                    else
                      echo "The only time you see this is when it positively does not."
                    fi
                    

                    【讨论】:

                      【解决方案12】:

                      以下命令应该可以解决这两种情况,

                      mysqlshow "DB_NAME" &> /dev/null && echo "YES" || echo "NO"
                      

                      【讨论】:

                      • 这是错误的。此命令将始终返回“YES”,因为 mysqlshow 将显示一个空的数据库列表,而不会失败,因为该命令将正确执行。您需要解析输出以了解列表是否为空。
                      • @Fabricio 手册页显示mysqlshow [db_name [tbl_name [col_name]]] 的签名,如果您指定的内容丢失,它将以非零值退出。如果是,则返回下一级的列表。
                      • @SteveBuzonas,你试过你的代码了吗?我做到了,它总是返回 YES。
                      • 我没有提供任何代码。我从手册页中展示了一个 sn-p。您的 mysqlshow 必须是不同的版本,因为我拥有的版本将与此解决方案一起使用。如果您查看man mysqlshow,您应该会看到该签名。您不需要解析任何内容,因为如果它不存在,它将退出非零,如果它确实存在,它将输出表并退出 0。
                      【解决方案13】:
                      mysql_user=<you_db_username>
                      mysql_pass=<you_db_passwrod>
                      target_db=<your_db_name>
                      if [ "`mysql -u${mysql_user} -p${mysql_pass} -e 'show databases;' | grep ${target_db}`" == "${target_db}" ]; then
                        echo "Database exist"
                      else
                        echo "Database does not exist"
                      fi
                      

                      这将执行 MySQL 查询以获取所有数据库名称,然后使用 greps 检查所需的数据库是否存在。

                      【讨论】:

                      • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
                      • @G4M1TG 这怎么不能回答问题?我同意几乎所有纯代码的答案都可以通过解释它的工作原理来改进,但这并不意味着这是一个非答案。
                      • 用ans给出更多描述。
                      • 希望现在更清楚了。 @G4M1TG 如果您对此仍有疑问,请提出。
                      【解决方案14】:

                      我还使用了与 chown 略有不同的版本。

                      result=$(mysqlshow --user=root --password=12345 dbname | grep -v Wildcard | grep -ow dbname)

                      上面执行给定的命令并将返回值分配给resultw 选项与 dbname 完全匹配。

                      【讨论】:

                        【解决方案15】:

                        mysqlshow 不会在数据库名称中显示下划线字符“_”。

                        mysqlshow $DOMAIN %
                        

                        https://dev.mysql.com/doc/refman/5.1/en/mysqlshow.html

                        【讨论】:

                          【解决方案16】:
                          if [ $(mysqlshow DB 1>/dev/null 2>/dev/null) -eq 0 ]; then
                              echo "DB found"
                          fi
                          

                          【讨论】:

                            【解决方案17】:
                            mysqlshow "test" > /dev/null 2>&1 && echo "Database exists."
                            

                            根据mysqlshow命令的退出状态,会执行如下回显。

                            【讨论】:

                            • 我认为这个答案会赢
                            • 这绝对行不通,至少在我的mysqlshow版本上是这样,因为无论数据库是否存在,命令都会返回成功,所以你必须解析输出。
                            • mysqlshow 对我有用,但使用 mysql 是另一种选择 mysql "test" -e exit &gt; /dev/null 2&gt;&amp;1 &amp;&amp; echo "Database exists.
                            • @gtd 将输出通过管道传输到您选择的文件,而不是 /dev/null。您可能会看到警告,例如“在命令行上使用密码...”,然后在下一行显示“mysqlshow:未知数据库'myDatabaseName'”。
                            • @KGCybeX:我明白,我的意思是这个答案不起作用,我不需要关于如何解决它的教程。
                            【解决方案18】:

                            我无法得到接受的答案(引号中的grep 不起作用),所以这是我的版本:

                            RESULT=`mysql -u $USER -p$PASSWORD --skip-column-names -e "SHOW DATABASES LIKE 'myDatabase'"`
                            if [ "$RESULT" == "myDatabase" ]; then
                                echo "Database exist"
                            else
                                echo "Database does not exist"
                            fi
                            

                            我使用选项 --skip-column-names 从结果中删除列名。

                            【讨论】:

                              【解决方案19】:

                              示例脚本(感谢 Bill Karwin 的 --user--password 评论!):

                              #!/bin/bash
                              ## --user=XXXXXX --password=XXXXXX *may* not be necessary if run as root or you have unsecured DBs but
                              ##   using them makes this script a lot more portable.  Thanks @billkarwin
                              RESULT=`mysqlshow --user=XXXXXX --password=XXXXXX myDatabase| grep -v Wildcard | grep -o myDatabase`
                              if [ "$RESULT" == "myDatabase" ]; then
                                  echo YES
                              fi
                              

                              这些是命令在提示符下运行时的样子:

                              [root@host ~]# mysqlshow myDatabase
                              Wildcard: myDatabase
                              +------------------+
                              |    Databases     |
                              +------------------+
                              | myDatabase       |
                              +------------------+
                              

                              如果不存在 DB,输出将如下所示:

                              [root@host ~]# mysqlshow myDatabase
                              Wildcard: myDatabase
                              +-----------+
                              | Databases |
                              +-----------+
                              +-----------+
                              

                              然后,解析输出并根据它是否存在做你需要做的事情!

                              【讨论】:

                              • +1 但您需要以具有该数据库权限的用户身份连接,否则结果中将丢失该数据库。
                              • @billk 经过测试,您是正确的,我想要使此功能正常工作,您需要使用 sudo 运行脚本。
                              • 不,你不需要 sudo,你只需要运行 mysqlshow --user=XXX --password=YYY 选项来为具有足够权限的用户指定 MySQL 凭据以查看相关数据库。
                              • 可能我的mysqlshow版本不一样,但是这样不行。如果我指定一个数据库名称作为最后一个参数,它要么在数据库标题下单独列出它,要么给出一个未知的数据库错误(如果它不存在)。如果我不指定数据库,它会给我数据库列表。我的 mysqlshow 的版本信息显示“mysqlshow Ver 9.10 Distrib 5.1.58, for debian-linux-gnu (i686)”
                              【解决方案20】:

                              for db in $(mysql -u -p -N <<<"show databases like '%something%'")
                              do
                                case $db in 
                                  "something")
                                    // do something
                                  ;;
                                  "something else")
                                    // do something else
                                  ;;
                                esac
                              done
                              

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 2019-05-12
                                • 1970-01-01
                                • 2012-11-29
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2010-10-24
                                相关资源
                                最近更新 更多