mysql - 在脚本中连接到 MySQL 服务器会返回错误,但在终端中可以正常工作
问题描述
我正在尝试编写一个 bash 脚本,它将自动安装和设置 MySQL 服务器。问题是当我的脚本执行以下命令时:
mysql --socket=<path-to-mysql-dir>/mysql/socket -u root -p"$pass"
我收到以下错误:
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/<path-to-mysql-dir>/mysql/socket' (2)
然而,当我在 bash 终端中运行相同的命令时,它运行良好:
$ mysql --socket=socket -u root -p'random-init-pass'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.18
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
这是设置:
我有一个名为sourceme.bash
. 我source sourceme.bash
为了设置服务器。这是它的样子(里面的一切<>
都不重要):
mysql/sourceme.bash
:
source /<path-to-bash-init>/bash
module load <modules>
SQLDIR="/<path-to-mysql-dir>"
cd $SQLDIR
# Kill the existing MySQL server (for testing purposes as I'm re-running this script multiple times)
# Do so by locating its process ID and terminating that ID, waiting until it's killed before proceeding.
ps -aux | grep mysql | grep -v grep
mysqlps=`ps -aux | grep mysql | grep -v grep | sed -e 's/ \{2,\}/ /g' | cut -f2 -d' '`
if [[ -n $mysqlps ]]; then
kill $mysqlps
while kill -0 $mysqlps; do
sleep 0.5
done
echo "MySQL process successfully killed. Status $?"
else
echo "No MySQL process to kill. Status $?"
fi
rm -rf $SQLDIR/mysql
# Set up MySQL server directory
mkdir -p $SQLDIR/mysql
pushd $SQLDIR/mysql
# Copy setup files stored in $SQLDIR in order to install MySQL
# The my.cnf config file contains the string "$USER" which should be replaced with a Unix username.
cat $SQLDIR/setup_files/my.cnf | awk -v user=`whoami` '{ sub(/\$USER/, user); print }' > my.cnf
cp -t . $SQLDIR/setup_files/loadmodules.bash $SQLDIR/setup_files/mysql_*
chmod +x mysql_*
# Load modules necessary to run the server
source loadmodules.bash
# Initialise MySQL server, kill the script if this step fails.
# NB thanks to Raman Sailopal for helping me with this bit: https://stackoverflow.com/questions/69406526/start-a-mysql-server-pipe-the-output-to-a-file
./mysql_init.sh 2>&1 | tee mysql_init.log
init_status=${PIPESTATUS[0]}
if [[ $init_status -ne 0 ]]; then
echo "Init script failed - kill script"
return 1
fi
# Grab the setup password from the log produced by mysql_init.sh. Copy into variable.
line=`tail -n1 mysql_init.log`
pass="${line##* }"
# Launch MySQL server now that it's been initialised
./mysql_start.sh
# Create a .my.cnf config file in the user's home area, set to user-access only
user=`whoami`
cat << EOT > ~/.my.cnf
[mysqld]
user=$user
password=$pass
socket=$SQLDIR/mysql/socket
EOT
chmod 700 ~/.my.cnf
# Fire up the MySQL server command line
# THIS IS THE BIT THAT DOESN'T WORK
mysql --socket=$SQLDIR/mysql/socket -u root -p"$pass"
如果我注释掉最后一行并将完全相同的内容复制到我的终端中,它将毫无怨言地启动 MySQL 服务器。我也尝试使用 -e 选项将命令输入 CLI,然后退出,但这也不起作用。
为了完整起见,这里是位于 $SQLDIR/mysql 位置的设置文件 - 脚本运行这些文件是为了启动 MySQL 服务器。
mysql/my.cnf
:
[mysqld]
user=lou-unix-username
socket=socket
mysql/mysql_init.sh
:
#! /bin/sh
export MYSQL_HOME=$PWD
# Change lc-messages-dir if running on RHE6 host
mysqld \
--defaults-file=$MYSQL_HOME/my.cnf \
--lc-messages-dir="/<path-to-mysql>/mysql/5.7.18/rhe7-x86_64/share/english/" \
--datadir=$MYSQL_HOME/data \
--basedir=$MYSQL_HOME \
--pid-file=$MYSQL_HOME/mysql.pid \
--socket=$MYSQL_HOME/socket \
--port=3307 \
--initialize
mysql/mysql_start.sh
:
#! /bin/sh
echo $DATADIR
export MYSQL_HOME=$PWD
mysqld \
--defaults-file=$MYSQL_HOME/my.cnf \
--log-error \
--lc-messages-dir="/<path-to-mysql>/mysql/5.7.18/rhe7-x86_64/share/english/" \
--datadir=$MYSQL_HOME/data \
--basedir=$MYSQL_HOME \
--pid-file=$MYSQL_HOME/mysql.pid \
--socket=$MYSQL_HOME/socket \
--port=3307 &
~/.my.cnf
:
[mysqld]
user=lou-unix-username
password=random-init-password
socket=/<path-to-mysql-dir>/mysql/socket
有没有人能建议为什么我可以在终端上启动 CLI 但不能在脚本中启动?我知道在启动 MySQL CLI 后我需要重置随机初始化的密码,但它甚至不允许我使用脚本执行此操作。我可能做错了什么?
解决方案
好吧,我不完全确定出了什么问题,但我认为这归结为一个进程在另一个进程开始之前没有完成。我在脚本中插入了一个sleep 5
- 就在我试图连接到服务器的最后一行之前,这很有效。我还将这条线包裹在一个while循环中,最多尝试5次连接到服务器,如果失败,它将再等待5秒。目前这似乎工作相当可靠,我能够连接到 MySQL 服务器。
因此,无论哪种方式,问题似乎都得到了解决。
推荐阅读
- javascript - 嵌套异步函数的空返回值
- c - 执行 copy_from_user() 时,用户和内核空间之间如何真正交换数据?
- java - 如何将一对整数的列表添加为 Map 中的值,其中键作为该对中的第一个值 - Java
- javascript - 为什么它会返回所有的小兵,而不仅仅是那些具有“升级者”角色的小兵?
- node.js - ExpressJs Uncaught TypeError:无法读取未定义 view.js 的属性“原型”
- android - 清单合并失败:uses-sdk:minSdkVersion 19 不能小于库中声明的版本 21
- amazon-web-services - AWS Lambda:如何为同一路径设置多个处理程序?
- javascript - 围绕折线图中的一个点画一条线
- python - 深拷贝与列表理解
- django - 如何更新 Django QuerySet,使其不返回缓存数据?