mysql 客户端在 运行 使用脚本时打印帮助消息,但 运行 直接在 shell 中就可以了
mysql client prints help message when run with script, but runs fine directly in shell
我遇到了一个奇怪的 shell 脚本问题。我正在尝试 运行 来自 shell 的 mysql
命令针对本地 docker 实例,或者通过 ssh 针对不可公开访问的数据库。我有这个:
#!/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=
DB_USER=
DB_PASSWORD=
DB_NAME=
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;'
,它就会返回打印 usage/help 消息.
当您 运行 它针对远程数据库时,您将 '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
我遇到了一个奇怪的 shell 脚本问题。我正在尝试 运行 来自 shell 的 mysql
命令针对本地 docker 实例,或者通过 ssh 针对不可公开访问的数据库。我有这个:
#!/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=
DB_USER=
DB_PASSWORD=
DB_NAME=
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;'
,它就会返回打印 usage/help 消息.
当您 运行 它针对远程数据库时,您将 '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