首页 > 解决方案 > 在脚本中连接到 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 后我需要重置随机初始化的密码,但它甚至不允许我使用脚本执行此操作。我可能做错了什么?

标签: mysqlbash

解决方案


好吧,我不完全确定出了什么问题,但我认为这归结为一个进程在另一个进程开始之前没有完成。我在脚本中插入了一个sleep 5- 就在我试图连接到服务器的最后一行之前,这很有效。我还将这条线包裹在一个while循环中,最多尝试5次连接到服务器,如果失败,它将再等待5秒。目前这似乎工作相当可靠,我能够连接到 MySQL 服务器。

因此,无论哪种方式,问题似乎都得到了解决。


推荐阅读