7

I am writing a script where I am want to launch the mysql_secure_installation script and provide the appropriate answers at each prompt. I tried using echo like this:

echo -e "\n\n$db_pass\n$db_pass\n\n\n\n\n" | /usr/bin/mysql_secure_installation

It doesn’t work completely. It seems that it answers the last 5 questions correctly but it doesn't answer the first 3 correctly (this is on a CentOS 6.5 box). Here is the output:

In order to log into MySQL to secure it, we'll need the current
password for the root user.  If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

stty: standard input: Invalid argument
Enter current password for root (enter for none):
stty: standard input: Invalid argument
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

Set root password? [Y/n]  ... skipping.

It should submit a return when asked for the root password. Then it should submit another return when asked to set the root password. However, as you can see from the output that is not happening.

What do I need to do in order to get this to work as expected?

2
  • 1
    I think either of the expect or pexpect (python-based expect) utilities are your best bet. May 6, 2014 at 21:14
  • yep, use expect May 6, 2014 at 21:16

2 Answers 2

6

This bug report on the MySQL dev site addresses the issue of mysql_secure_installation requiring an interactive user session.

There is some good discussion there that has some tips and examples that make use of expect as a workaround. The best advice that seems to address your desire to run the script non-interactively (i.e.: without direct user interaction) is the answer by Daniël van Eeden which provides the following expect script:

#!/usr/bin/expect --
spawn /usr/local/mysql/bin/mysql_secure_installation

expect "Enter current password for root (enter for none):"
send "\r"

expect "Set root password?"
send "y\r"

expect "New password:"
send "password\r"

expect "Re-enter new password:"
send "password\r"

expect "Remove anonymous users?"
send "y\r"

expect "Disallow root login remotely?"
send "y\r"

expect "Remove test database and access to it?"
send "y\r"

expect "Reload privilege tables now?"
send "y\r"

puts "Ended expect script."

Also, it seems like the overarching issue of base MySQL installs having non-secure stuff in place seems to be addressed in MySQL 5.6.8 but only for new installs via RPMs or source code installs that are made with the --random-password option:

New RPM install operations (not upgrades) invoke mysql_install_db with the --random-passwords option. As a consequence, RPM installs from this version onward will have their root accounts secured, and will have no anonymous-user accounts. (Install operations using RPMs for Unbreakable Linux Network are unaffected because they do not use mysql_install_db.)

For install operations using a binary .tar.gz distribution or a source distribution, you can invoke mysql_install_db with the --random-passwords option manually to make your MySQL installation more secure. This is recommended, particularly for sites with sensitive data.

4
  • 1
    Nicely written detailed answer (+1). I never heard of expect before but it will be something I will definitely look into. I like both answers, not sure which one to pick.
    – user5013
    May 6, 2014 at 21:36
  • 1
    @JakeGould just as a note, the script is an expect script, not a bash script.
    – DerfK
    May 6, 2014 at 21:42
  • 1
    For those who want an entirely scripted install with MySQL 5.6+ on Ubuntu 16.04 LTS, see my post here: serverfault.com/questions/783527/… Jun 12, 2016 at 21:57
  • @JakeGould Thank you so much. Referred a lot but at last, your solution worked for me. Jan 11, 2019 at 8:51
7

You can't do that. If you want to interact with a script you have to use something like expect(1) - there are examples here on SF and on the wider internet of how to do this.

You can emulate much of the mysql_secure_Installation with

/usr/bin/mysql -uroot -e "DELETE FROM mysql.user WHERE User=\'\'; DELETE FROM mysql.user WHERE User=\'root\' AND Host NOT IN (\'localhost\', \'127.0.0.1\', \'::1\'); DROP DATABASE IF EXISTS test; FLUSH PRIVILEGES;"

All you need to do after that is set a root password.

2
  • Thanks for that answer, that makes it easy to include within a bash script. It is simple and to the point.
    – user5013
    May 6, 2014 at 21:34
  • +1 for nice & easy solution.... Aug 8, 2014 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.