【发布时间】:2023-03-07 14:39:02
【问题描述】:
是否可以在 bash 脚本中检查 mysql 数据库是否存在。然后根据结果执行另一个操作或终止脚本?
【问题讨论】:
是否可以在 bash 脚本中检查 mysql 数据库是否存在。然后根据结果执行另一个操作或终止脚本?
【问题讨论】:
在mysql 命令中使用-e 选项。它会让你执行任何查询(假设有正确的凭据)。
这可能是一个例子:
if mysql "DATABASE_NAME" -e exit > /dev/null 2>&1; then
echo "Exists"
else
echo "Not exists"
fi
【讨论】:
这是我在 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
【讨论】:
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."
【讨论】:
您也可以要求使用数据库,然后处理退出代码。
$ 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'
或者检查$?通话后。
【讨论】:
我给answer by @chown +1,但这里有另一种选择:如果 bash 脚本与 MySQL 实例一起在本地运行,并且您知道 datadir 的路径,则可以测试:
if [ -d /var/lib/mysql/databasename ] ; then
# Do Stuff ...
fi
这还假设您运行脚本的 shell 用户具有文件系统级别的权限来读取 MySQL 数据目录的内容。这种情况经常发生,但并不确定。
【讨论】:
file_per_table。路径取决于操作系统。
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,因此您仍然可以使用非零状态来报告错误,而不是让不存在的数据库显示为错误。
【讨论】:
如果有帮助,我在 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% 可靠,例如连接失败或其他情况。 (我没有测试过。)
【讨论】:
这是另一个版本:
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。
【讨论】:
abcd 和 abcd_xyz?
没有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:
注意事项:
MYSQL_PWD 禁用警告:
mysql: [警告] 在命令行界面使用密码可能不安全。
--skip-column-names 隐藏列
--batch 禁用像+-----------+ 这样的边框
【讨论】:
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
【讨论】:
使用 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
【讨论】:
以下命令应该可以解决这两种情况,
mysqlshow "DB_NAME" &> /dev/null && echo "YES" || echo "NO"
【讨论】:
mysqlshow [db_name [tbl_name [col_name]]] 的签名,如果您指定的内容丢失,它将以非零值退出。如果是,则返回下一级的列表。
mysqlshow 必须是不同的版本,因为我拥有的版本将与此解决方案一起使用。如果您查看man mysqlshow,您应该会看到该签名。您不需要解析任何内容,因为如果它不存在,它将退出非零,如果它确实存在,它将输出表并退出 0。
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 检查所需的数据库是否存在。
【讨论】:
我还使用了与 chown 略有不同的版本。
result=$(mysqlshow --user=root --password=12345 dbname | grep -v Wildcard | grep -ow dbname)
上面执行给定的命令并将返回值分配给result。 w 选项与 dbname 完全匹配。
【讨论】:
mysqlshow 不会在数据库名称中显示下划线字符“_”。
mysqlshow $DOMAIN %
【讨论】:
if [ $(mysqlshow DB 1>/dev/null 2>/dev/null) -eq 0 ]; then
echo "DB found"
fi
【讨论】:
mysqlshow "test" > /dev/null 2>&1 && echo "Database exists."
根据mysqlshow命令的退出状态,会执行如下回显。
【讨论】:
mysqlshow 对我有用,但使用 mysql 是另一种选择 mysql "test" -e exit > /dev/null 2>&1 && echo "Database exists.
/dev/null。您可能会看到警告,例如“在命令行上使用密码...”,然后在下一行显示“mysqlshow:未知数据库'myDatabaseName'”。
我无法得到接受的答案(引号中的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 从结果中删除列名。
【讨论】:
示例脚本(感谢 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 |
+-----------+
+-----------+
然后,解析输出并根据它是否存在做你需要做的事情!
【讨论】:
sudo 运行脚本。
mysqlshow --user=XXX --password=YYY 选项来为具有足够权限的用户指定 MySQL 凭据以查看相关数据库。
是
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
【讨论】: