如何解决mysql 客户端在使用脚本运行时打印帮助消息,但直接在 shell 中运行良好
我遇到了一个奇怪的 shell 脚本问题。我正在尝试从 shell 针对本地 docker 实例或通过 ssh 针对不可公开访问的数据库运行 MysqL
命令。我有这个:
#!/bin/bash
# 0: Check DB status
# 1: Query MysqL for latest migration
# 2: Check sql dir for migrations newer than query result
# 3..: Execute newer sql *in order*
################################################################################
# script and sql calls
################################################################################
DB_HOST=$1
DB_USER=$2
DB_PASSWORD=$3
DB_NAME=$4
if [[ -z $REMOTE_HOST ]]; then
SSH_PREFIX=""
else
SSH_PREFIX="ssh -o StrictHostKeyChecking=no -i sshkey ${REMOTE_USER}@${REMOTE_HOST}"
fi
MysqL_CLIENT="MysqL --protocol=tcp -h ${DB_HOST} -u ${DB_USER} --password=${DB_PASSWORD}"
#checking MysqL connection
MysqL_db_statuscheck(){
echo "`date` :Checking DB connectivity...";
echo "`date` :Trying to connect to the ODU MysqL Database..."
EXEC_sql="-e 'SELECT 1;'"
cmd="${SSH_PREFIX} ${MysqL_CLIENT} ${EXEC_sql} ${DB_NAME}"
echo $cmd
$cmd
if [[ $? -eq 0 ]]
then
DB_STATUS="UP"
export DB_STATUS
echo "`date` :Status: ${DB_STATUS}. Able to Connect..."
else
DB_STATUS="DOWN"
export DB_STATUS
echo "`date` :Status: DOWN . Not able to Connect."
echo "`date`:Not able to connect to database with Username:
"${DB_USER}" HostName: ""${DB_HOST}" " SID: "${DB_NAME}"."
echo "`date` :Exiting Script Run..."
exit 1
fi
}
# run MysqL function
runMysqLs() {
echo "`date` :Checking DB and table status..."
MysqL_db_statuscheck
echo "`date` :DB status check completed"
echo "`date` :Connecting To ${DB_USER}/******@${DB_NAME}";
if [[ $DB_STATUS == "UP" ]]
then
# latest_migration will be an int
EXEC_sql='--execute="SELECT MAX(version) FROM migrations;"'
latest_migration=`$SSH_PREFIX $MysqL_CLIENT ${EXEC_sql} ${DB_NAME} 2>&1`
if [[ `echo "${latest_migration}" |cut -c 1-10` == "ERROR 1146" ]]; then
echo "`date` :Running initial migration"
latest_migration=0
fi
for file in `ls ./sql`; do
file_migration_no=`echo "$file" |cut -c1-3`
if [[ $latest_migration -lt $file_migration_no ]]; then
echo "`date` :Executing migration $file_migration_no from file $file...";
echo "`date` :__________________________________________";
echo "`date` :sql OUTPUT:";
echo "`date` :__________________________________________";
TAIL="-se '`cat ./sql/${file}`'"
sqlout=`$SSH_PREFIX $MysqL_CLIENT ${TAIL} 2>&1`
if [[ $? -eq 0 ]]; then
TAIL="-se 'INSERT INTO migrations (version) VALUES (${file_migration_no});'"
`$SSH_PREFIX $MysqL_CLIENT ${TAIL}`
else
echo ${sqlout}
exit 1
fi
fi
done
else
echo "`date` :Either the DB is down or the exit status returned by
the script shows ERROR."
echo "`date` :Exiting ..."
exit
fi
}
# main function
Main() {
echo "`date` :Starting sql auto run script."
runMysqLs
echo "`date` :sql auto run script execution completed."
}
Main
当我对远程数据库运行它时,它运行良好。但是当我针对本地实例运行时,它只是打印出 MysqL 帮助消息。
我正在打印要运行的命令,$ MysqL --protocol=tcp -h localhost -u root --password=hotdog99 -e 'SELECT 1;' cooldb
但是如果我将脚本输出中的内容复制并粘贴到终端中,它运行良好!
如果我设置
EXEC_sql=""
它让我进入 MysqL shell,但只要插入 -e 'SELECT 1;'
或 --execute='SELECT 1;'
,它就会返回打印使用/帮助消息。
解决方法
当您针对远程数据库运行它时,您将把 'SELECT 1;'
传递给 ssh
,后者将它作为命令行参数传递给 shell,而该 shell 会去掉单引号 ( ''
) 符合预期。
当您在本地运行它时,您只是在取消引用一个变量。您没有将它作为参数传递给 shell,因此它会按原样扩展,这意味着您传递给 mysql
的参数是 'SELECT 1;'
,即带引号。
您应该改用 sh -c "$cmd"
。
演示:
$ ARG="'hello'"
$ cmd="echo ${ARG}"
$ echo $cmd
echo 'hello'
$ $cmd
'hello'
$ sh -c "$cmd"
hello
$ cmd="ssh 0 echo ${ARG}"
$ $cmd
hello
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。