Sign up ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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?

share|improve this question
I think either of the expect or pexpect (python-based expect) utilities are your best bet. – Sean Staats May 6 '14 at 21:14
yep, use expect – Michael Martinez May 6 '14 at 21:16

2 Answers 2

up vote 4 down vote accepted

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 & 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.

share|improve this answer
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 '14 at 21:36
@JakeGould just as a note, the script is an expect script, not a bash script. – DerfK May 6 '14 at 21:42
@DerfK Thanks for the clarification! – JakeGould May 6 '14 at 21:43

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\', \'\', \'::1\'); DROP DATABASE IF EXISTS test; FLUSH PRIVILEGES;"

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

share|improve this answer
Thanks for that answer, that makes it easy to include within a bash script. It is simple and to the point. – user5013 May 6 '14 at 21:34
+1 for nice & easy solution.... – Harikrishnan Aug 8 '14 at 10:00

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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