Connecting to MySQL server in a script returns error, but it works fine in a terminal

Viewed 68

I'm trying to write a bash script which will install and set up a MySQL server automatically. The problem is that when my script executes the following command:

mysql --socket=<path-to-mysql-dir>/mysql/socket -u root -p"$pass"

I get the following error:

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)

Yet when I run the same command in my bash terminal, it works fine:

$ 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> 

Here's the set-up:

I have a script called sourceme.bash. I source sourceme.bash in order to set up the server. Here's what it looks like (everything in <> is unimportant):

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"

If I comment out the last line and copy the exact same thing into my terminal, it will start the MySQL server without complaint. I've also tried using the -e option to feed a command into the CLI and then quit, but that doesn't work either.

For completeness, here are the setup files that will be in the location $SQLDIR/mysql - which the script runs in order to start the MySQL server.

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

Is anyone able to suggest why I can launch the CLI on the terminal but not in a script? I know that I need to reset the randomly initialised password after starting up the MySQL CLI, but it won't even let me do that using the script. What could I be doing wrong?

1 Answers

Well, I'm not entirely sure what was wrong, but I think it came down to one process not finishing before another process started. I inserted a sleep 5 in the script - just before the last line where I'm trying to connect to the server, and that worked. I also wrapped the line in a while loop, giving it up to 5 attempts to connect to the server, and if it fails, it will wait a further 5 seconds. Currently this seems to work fairly reliably and I am able to connect to the MySQL server.

So either way the problem appears to be solved.

Related