30

I have a MySQL server with an user with a password. I want to execute some SQL queries in shell scripts without specifying the password like this:

config.sh:

MYSQL_ROOT="root"
MYSQL_PASS="password"

mysql.sh:

source config.sh
mysql -u$MYSQL_ROOT -p$MYSQL_PASS -e "SHOW DATABASES"

How can I simplify the whole process in order to execute SQL queries without specifying the -p and -u argument etc.?

2
  • 3
    A word of advice: You should get into the habit of setting passwords on your databases. Also, it's probably not a good idea to use your root user to do everyday stuff, either. Create a user with limited privileges for doing queries. Commented Dec 11, 2012 at 5:57
  • 2
    General advice: Don't give passwords as command line arguments. They can be seen by any user logged in on the machine, even if the command only takes a fraction of a second. Commented Sep 26, 2019 at 14:43

5 Answers 5

59

Alternative ways to write these options.

You can write

mysql -u "$MYSQL_ROOT" -p"$MYSQL_PASS" -e "SHOW DATABASES"

If [password is] given, there must be no space between --password= or -p and the password following it. If no password option is specified, the default is to send no password.

to pass empty strings as separate arguments. Your comment below indicates that the client will still ask for a password, though. Probably it interprets the empty argument as a database name and not as the password. So you could try the following instead:

mysql --user="$MYSQL_ROOT" --password="$MYSQL_PASS" -e "SHOW DATABASES"

.my.cnf file

But even if there is a way, I'd still suggest you use a ~/.my.cnf file instead. Arguments on the command line are likely included in a process listing generated by ps -A -ocmd, so other users can see them. The .my.cnf file, on the other hand, can (and should) be made readable only by you (using chmod 0600 ~/.my.cnf), and will be used automatically. Have that file include the following lines:

[client]
user=root
password=

Then a simple mysql -e "SHOW DATABASES" will suffice, as the client will obtain its credentials from that file.

See 6.1.2.1. End-User Guidelines for Password Security for the various ways in which you can provide a password, and their respective benefits and drawbacks. See 4.2.3.3. Using Option Files for general information on this .my.cnf file

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you. If I use: mysql -u "$MYSQL_ROOT" -p "$MYSQL_PASS" -e "SHOW DATABASES", bash still ask me to Enter password
There can't be any space after the -p option. It must look like: -pMyPassHere or -p'My Pass Here'.
Shouldn't this be the accepted answer? Particularly since it offers the highly relevant .my.cnf option?
Using .my.cnf file in home is the best choice for me. And as you mention permissions are important here. Works like a charm. Thanks.
This should be the accepted answer. Unless there is a better option as a matter of password security.
16

As MvG suggested (recommended in the MySQL manual 4.2.2 connecting and 6.1.2.1 security guidelines) you should use a file. The password on the command line may be unsafe since ps may show it to other users. The file does not have to be .my.cnf, can be an ad-hoc option file for your script in a temporary file:

OPTFILE="$(mktemp -q --tmpdir "${inname}.XXXXXX")$"
trap 'rm -f "$OPTFILE"' EXIT
chmod 0600 "$OPTFILE"
cat >"$OPTFILE" <<EOF
[client]
password="${MYSQL_PASS}"
EOF
mysql --user="$MYSQL_ROOT" --defaults-extra-file="$OPTFILE" -e "SHOW DATABASES"

The first lines create a safe temp file, then put the options then use it. trap will protect you form OPTFILE lying around in case of interrupts.

2 Comments

@ranind suggested changing the order in the command line to mysql --defaults-extra-file="$OPTFILE" --user="$MYSQL_ROOT" -e "SHOW DATABASES" to avoid "unknown variable" error. Both orders worked for me.
This is a great answer: portable, and as secure as this method can be.
15

Try this:

if [ $MYSQL_PASS ]
then
  mysql -u "$MYSQL_ROOT" -p"$MYSQL_PASS" -e "SHOW DATABASES"
else
  mysql -u "$MYSQL_ROOT" -e "SHOW DATABASES"
fi

6 Comments

I might be wrong, but as far as I recall, an empty password and no password at all are different things for MySQL.
@MvG, not correct. An empty password and no password are treated the same. Try it: choose a login with no password, use -p and when it prompts you, hit return.
N.B This answer is wrong, since there should be no space after the -p option. Generally speaking using a defaults file is a better way to go (should be only readable by user, so chmod 600) : mysql -u "$MYSQL_ROOT" --defaults-file=/tmp/my.cnf -e "SHOW DATABASES"
passwords should not be inserted into a command line, by bash or by user. It is very insecure. The -p is also wrong as there should not be a space, thankfully, as users should definitely not do this!
But put password in command line is insecure. Any user can see password by ps
|
11

Here is a little bash script you can use to get a shell really quickly

It opens up a shell so you can manually execute queries. Very convenient.

  #!/bin/bash
  DB_USER='your_db_username'
  DB_PASS='your_password'
  DB='database_name'
  echo 'logging into db $DB as $DB_USER'
  mysql -u "$DB_USER" --password="$DB_PASS" --database="$DB"

Comments

1

To auto login in MySQL using Debian GNU/Linux distributions (like Ubuntu, Xubuntu, Linux Mint, gNewSense, etc. etc.) you can simply use the already existing file /etc/mysql/debian.cnf that contains valid superuser credentials.

So, you can try to auto login with this simple command:

sudo mysql --defaults-file=/etc/mysql/debian.cnf

If it works, to avoid to remember the above command you can also create some Bash aliases. You can do it pasting these commands in your user terminal:

echo ''                                                                       >> ~/.bashrc
echo "# Auto-login in MySQL"                                                  >> ~/.bashrc
echo "# From https://stackoverflow.com/a/33584904/3451846"                    >> ~/.bashrc
echo "alias mysql='sudo mysql --defaults-file=/etc/mysql/debian.cnf'"         >> ~/.bashrc
echo "alias mysqldump='sudo mysqldump --defaults-file=/etc/mysql/debian.cnf'" >> ~/.bashrc
. ~/.bashrc

And then just type this to auto login:

mysql

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.