You can avoid re-entering mysql command line password by putting the queries into a file.
In my case, the later queries are not determined until after the first queries have finished.
This happens in a non-interactive script so running a mysql console is not an option.
Is there any notion of a session for mysql command line interactions? Or can I set it up to listen for commands on a local unix socket (the output is required to be returned)? Or something like that?
User #smcjones mentions using the .my.cnf file or mysql_config_editor. Those are good suggestions, I give my +1 vote to him.
Another solution is to put the credentials in any file of your choosing and then specify that file when you invoke MySQL tools:
mysql --defaults-extra-file=my_special.cnf ...other arguments...
And finally, just for completeness, you can use environment variables for some options, like host and password. But strangely, not the user. See http://dev.mysql.com/doc/refman/5.7/en/environment-variables.html
export MYSQL_HOST="mydbserver"
export MYSQL_PWD="Xyzzy"
mysql ...other arguments...
I don't really recommend using an environment variable for the password, since anyone who can run ps on your client host can see the environment variables for the mysql client process.
There are a few ways to handle this in MySQL.
Put password in hidden .my.cnf in the home directory of the user the script is running as.
[client]
user=USER
password=PASSWORD
Use mysql_config_editor
mysql_config_editor set --login-path=client --host=localhost
--user=localuser --password
When prompted to enter your password, enter it like you otherwise would.
IMO this is the worst option, but I'll add it for the sake of completeness.
You could always create a function wrapper for MySQL that appends your set password.
#! /bin/bash
local_mysql_do_file() {
mysql -u localuser -h localhost -pPASSWORD_NO_SPACE < $1
}
# usage
local_mysql_do_file file.sql
I want to run mysql client, giving the password non-interactively.
The standard solution is this
mysql -u root -e "foo" -p < password_file
but my situation is this
produce_password | mysql -u root -p
Here, mysql prompts for a password, even though data is being piped in. (Yes, produce_password is emitting data; echo foo | mysql behaves the same way.)
The Internet seems to think the above should work, but the fact is it doesn't. The workaround would be
produce_password > password_file
mysql -u root -p < password_file
rm password_file
But let's say I don't want to do this (e.g. policy demands that this password never be written to the disk)
How can I make mysql take the password from the input process without prompting, as it would for a file?
With thanks to fancyPants for explaining the cause, here is a solution which meets my requirements. (The encrypted .mylogin.cnf with mysql_config_editor isn't right for me, but thanks.)
To satisfy the security policy, mount /ramfs as a ramfs temporary file system. Assume file permissions are suitably restrictive.
ramdir="/ramfs"
cnf="$(mktemp "$ramdir/this-script-name-XXXXX")"
pw="$(produce_password)"
cat >"$cnf" <<EOF
[client]
user=root
password="$pw"
EOF
mysql --defaults-extra-file="$cnf" -e 'select 1'
rm "$cnf"
the problem with that is the password shows up in the process list.
But you can do this.
mysql --defaults-file=<(echo '[client]'; echo 'user=USERNAME'; echo "password=$mysqlpassword";)
It shows up in the process list like this.
mysql --defaults-file=/dev/fd/63
so the <() creates a file handle to the output of your commands.
This works with command line options that are expecting a file.
I don't know how to explain this, but when you pipe something, the stdout of the first program is forwarded to the stdin of the second program. You somehow confuse this, with the command line or whatever. You can pipe something to mysql, of course, but whatever you pipe is handled after you've authenticated yourself.
The solution would be
mysql -u root -p$(produce_password)
This generates your password with whatever program you have there and puts it in the right place on your commandline (my english is bad, can't explain better). When you have it in a file you could do
mysql -u root -p$(cat file)
I don't know, why you want to do it this way anyway, but you might be interested in having an encrypted file with your credentials, that you can use to log in without specifying a password. Read more about it here.
The easiest way is to declare the environment variable MYSQL_PWD.
Example:
$ export MYSQL_PWD=$(produce the password if required)
$ mysql -h example.org -u username
Remember you should not use -p in this case.
I'm studying MySQL, and every time I have to
Enter ssh XXX#XXX command, and enter my password to the school server.
Enter mysql -u XXX -p command, and enter MySQL password.
I want to create a Bash script for performing the steps above automatically.
I can accomplish the first step with this code:
#!/usr/bin/expect -f
set address xxx.com
set password xxx
set timeout 10
spawn ssh xxx#$address
expect { "*yes/no" { send "yes\r"; exp_continue} "*password:" { send "$password\r" } }
send clear\r
interact
But I don't know how to automatically input the next command (mysql -u xxx -p) and the password.
How can I do this?
You don't need such a complex script to just enter the MySQL console on remote machine. Use the features of the ssh tool:
ssh -tt user#host -- mysql -uuser -ppassword
The -t option forces pseudo-terminal allocation. Multiple -t force tty allocation, even if ssh has no local tty (see man ssh). Note the use of -p option. There must be no spaces between -p and password (see the manual for mysql).
Or even connect via mysql directly, if the MySQL host is accessible from your local machine:
mysql -hhost -uuser -p
Don't forget to adjust the shebang:
#!/bin/bash -
Use my.cnf to store your password securly like ssh keys.
https://easyengine.io/tutorials/mysql/mycnf-preference/
Same way ssh is also possible through ssh -i parameter and passing the private key path of the remote host.
Best of luck!
You can avoid re-entering mysql command line password by putting the queries into a file.
In my case, the later queries are not determined until after the first queries have finished.
This happens in a non-interactive script so running a mysql console is not an option.
Is there any notion of a session for mysql command line interactions? Or can I set it up to listen for commands on a local unix socket (the output is required to be returned)? Or something like that?
User #smcjones mentions using the .my.cnf file or mysql_config_editor. Those are good suggestions, I give my +1 vote to him.
Another solution is to put the credentials in any file of your choosing and then specify that file when you invoke MySQL tools:
mysql --defaults-extra-file=my_special.cnf ...other arguments...
And finally, just for completeness, you can use environment variables for some options, like host and password. But strangely, not the user. See http://dev.mysql.com/doc/refman/5.7/en/environment-variables.html
export MYSQL_HOST="mydbserver"
export MYSQL_PWD="Xyzzy"
mysql ...other arguments...
I don't really recommend using an environment variable for the password, since anyone who can run ps on your client host can see the environment variables for the mysql client process.
There are a few ways to handle this in MySQL.
Put password in hidden .my.cnf in the home directory of the user the script is running as.
[client]
user=USER
password=PASSWORD
Use mysql_config_editor
mysql_config_editor set --login-path=client --host=localhost
--user=localuser --password
When prompted to enter your password, enter it like you otherwise would.
IMO this is the worst option, but I'll add it for the sake of completeness.
You could always create a function wrapper for MySQL that appends your set password.
#! /bin/bash
local_mysql_do_file() {
mysql -u localuser -h localhost -pPASSWORD_NO_SPACE < $1
}
# usage
local_mysql_do_file file.sql
I would like to know the command to perform a mysqldump of a database without the prompt for the password.
REASON:
I would like to run a cron job, which takes a mysqldump of the database once everyday. Therefore, I won't be able to insert the password when prompted.
How could I solve this ?
Since you are using Ubuntu, all you need to do is just to add a file in your home directory and it will disable the mysqldump password prompting. This is done by creating the file ~/.my.cnf (permissions need to be 600).
Add this to the .my.cnf file
[mysqldump]
user=mysqluser
password=secret
This lets you connect as a MySQL user who requires a password without having to actually enter the password. You don't even need the -p or --password.
Very handy for scripting mysql & mysqldump commands.
The steps to achieve this can be found in this link.
Alternatively, you could use the following command:
mysqldump -u [user name] -p[password] [database name] > [dump file]
but be aware that it is inherently insecure, as the entire command (including password) can be viewed by any other user on the system while the dump is running, with a simple ps ax command.
Adding to #Frankline's answer:
The -p option must be excluded from the command in order to use the password in the config file.
Correct:
mysqldump –u my_username my_db > my_db.sql
Wrong:
mysqldump –u my_username -p my_db > my_db.sql
.my.cnf can omit the username.
[mysqldump]
password=my_password
If your .my.cnf file is not in a default location and mysqldump doesn't see it, specify it using --defaults-file.
mysqldump --defaults-file=/path-to-file/.my.cnf –u my_username my_db > my_db.sql
A few answers mention putting the password in a configuration file.
Alternatively, from your script you can export MYSQL_PWD=yourverysecretpassword.
The upside of this method over using a configuration file is that you do not need a separate configuration file to keep in sync with your script. You only have the script to maintain.
There is no downside to this method.
The password is not visible to other users on the system (it would be visible if it is on the command line). The environment variables are only visible to the user running the mysql command, and root.
The password will also be visible to anyone who can read the script itself, so make sure the script itself is protected. This is in no way different than protecting a configuration file. You can still source the password from a separate file if you want to have the script publicly readable (export MYSQL_PWD=$(cat /root/mysql_password) for example). It is still easier to export a variable than to build a configuration file.
E.g.,
$ export MYSQL_PWD=$(>&2 read -s -p "Input password (will not echo): "; echo "$REPLY")
$ mysqldump -u root mysql | head
-- MySQL dump 10.13 Distrib 5.6.23, for Linux (x86_64)
--
-- Host: localhost Database: mysql
-- ------------------------------------------------------
-- Server version 5.6.23
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */;
/*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
MariaDB
MariaDB documents the use of MYSQL_PWD as:
Default password when connecting to mysqld. It is strongly recommended to use a more secure method of sending the password to the server.
The page has no mentions of what a "more secure" method may be.
MySQL
This method is still supported in the latest documented version of MySQL: https://dev.mysql.com/doc/refman/8.0/en/environment-variables.html though it comes with the following warning:
Use of MYSQL_PWD to specify a MySQL password must be considered extremely insecure and should not be used. Some versions of ps include an option to display the environment of running processes. On some systems, if you set MYSQL_PWD, your password is exposed to any other user who runs ps. Even on systems without such a version of ps, it is unwise to assume that there are no other methods by which users can examine process environments.
The security of environment variables is covered in much details at https://security.stackexchange.com/a/14009/10002 and this answer also addresses the concerns mentioned in the comments. TL;DR Irrelevant for over a decade.
Having said that, the MySQL documentation also warns:
MYSQL_PWD is deprecated as of MySQL 8.0; expect it to be removed in a future version of MySQL.
To which I'll leave you with maxschlepzig's comment from below:
funny though how Oracle doesn't deprecate passing the password on the command line which in fact is extremely insecure
Final thoughts
Connecting to a system using a single factor of authentication (password) is indeed insecure. If you are worried about security, you should consider adding mutual TLS on top of the regular connection so both the server and the client are properly identified as being authorized.
To use a file that is anywhere inside of OS, use --defaults-extra-file eg:
mysqldump --defaults-extra-file=/path/.sqlpwd [database] > [desiredoutput].sql
Note: .sqlpwd is just an example filename. You can use whatever you desire.
Note: MySQL will automatically check for ~/.my.cnf which can be used instead of --defaults-extra-file
If your using CRON like me, try this!
mysqldump --defaults-extra-file=/path/.sqlpwd [database] > "$(date '+%F').sql"
Required Permission and Recommended Ownership
sudo chmod 600 /path/.sqlpwd && sudo chown $USER:nogroup /path/.sqlpwd
.sqlpwd contents:
[mysqldump]
user=username
password=password
Other examples to pass in .cnf or .sqlpwd
[mysql]
user=username
password=password
[mysqldiff]
user=username
password=password
[client]
user=username
password=password
If you wanted to log into a database automatically, you would need the [mysql] entry for instance.
You could now make an alias that auto connects you to DB
alias whateveryouwant="mysql --defaults-extra-file=/path/.sqlpwd [database]"
You can also only put the password inside .sqlpwd and pass the username via the script/cli. I'm not sure if this would improve security or not, that would be a different question all-together.
For completeness sake I will state you can do the following, but is extremely insecure and should never be used in a production environment:
mysqldump -u [user_name] -p[password] [database] > [desiredoutput].sql
Note: There is NO SPACE between -p and the password.
Eg -pPassWord is correct while -p Password is incorrect.
Yeah it is very easy .... just in one magical command line no more
mysqldump --user='myusername' --password='mypassword' -h MyUrlOrIPAddress databasename > myfile.sql
and done :)
For me, using MariaDB I had to do this: Add the file ~/.my.cnf and change permissions by doing chmod 600 ~/.my.cnf. Then add your credentials to the file. The magic piece I was missing was that the password needs to be under the client block (ref: docs), like so:
[client]
password = "my_password"
[mysqldump]
user = root
host = localhost
If you happen to come here looking for how to do a mysqldump with MariaDB. Place the password under a [client] block, and then the user under a [mysqldump] block.
You can achieve this in 4 easy steps
create directory to store script and DB_backups
create ~/.my.cnf
create a ~/.script.sh shell script to run the mysqldump
Add a cronjob to run the mysql dump.
Below are the detailed steps
Step 1
create a directory on your home directory using sudo mkdir ~/backup
Step 2
In your home directory run sudo nano ~/.my.cnf and add the text below and save
[mysqldump]
#use this if your password has special characters (!##$%^&..etc) in it
password="YourPasswordWithSpecialCharactersInIt"
#use this if it has no special characters
password=myPassword
Step 3
cd into ~/backup and create another file script.sh
add the following text to it
SQLFILE=/path/to/where/you/want/to/dump/dbname.sql
DATABASE=dbname
USER=myUsername
mysqldump --defaults-file=~/.my.cnf -u ${USER} ${DATABASE}|gzip > dbName_$(date +\%Y\%m\%d_\%H\%M).sql.gz
Step 4
In your console, type crontab -e to open up the cron file where the auto-backup job will be executed from
add the text below to the bottom of the file
0 0 * * * ./backup/script.sh
The text added to the bottom of the cron file assumes that your back up shall run daily at midnight.
That's all you need folk
;)
Here is a solution for Docker in a script /bin/sh :
docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec echo "[client]" > /root/mysql-credentials.cnf'
docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec echo "user=root" >> /root/mysql-credentials.cnf'
docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec echo "password=$MYSQL_ROOT_PASSWORD" >> /root/mysql-credentials.cnf'
docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec mysqldump --defaults-extra-file=/root/mysql-credentials.cnf --all-databases'
Replace [MYSQL_CONTAINER_NAME] and be sure that the environment variable MYSQL_ROOT_PASSWORD is set in your container.
Hope it will help you like it could help me !
Check your password!
Took me a while to notice that I was not using the correct user name and password in ~/.my.cnf
Check the user/pass basics before adding in extra options to crontab backup entries
If specifying --defaults-extra-file in mysqldump then this has to be the first option
A cron job works fine with .my.cnf in the home folder so there is no need to specify --defaults-extra-file
If using mysqlpump (not mysqldump) amend .my.cnf accordingly
The ~/.my.cnf needs permissions set so only the owner has read/write access with:
chmod 600 ~/.my.cnf
Here is an example .my.cnf:
[mysql]
host = localhost
port = 3306
user = BACKUP_USER
password = CORRECTBATTERYHORSESTAPLE
[mysqldump]
host = localhost
port = 3306
user = BACKUP_USER
password = CORRECTBATTERYHORSESTAPLE
[mysqlpump]
host = localhost
port = 3306
user = BACKUP_USER
password = CORRECTBATTERYHORSESTAPLE
The host and port entries are not required for localhost
If your user name in linux is the same name as used for your backup purposes then user is not required
Another tip, whilst you are doing a cronjob entry for mysqldump is that you can set it to be a low priority task with ionice -c 3 nice 19. Combined with the --single-transaction option for InnoDB you can run backups that will not lock tables or lock out resources that might be needed elsewhere.
I have the following.
/etc/mysqlpwd
[mysql]
user=root
password=password
With the following alias.
alias 'mysql -p'='mysql --defaults-extra-file=/etc/mysqlpwd'
To do a restore I simply use:
mysql -p [database] [file.sql]
This is how I'm backing-up a MariaDB database using an expanding variable.
I'm using a "secrets" file in a Docker-Compose setup to keep passwords out of Git, so I just cat that in an expanding variable in the script.
NOTE: The below command is executed from the Docker host itself:
mysqldump -h192.168.1.2 -p"$(cat /docker-compose-directory/mariadb_root_password.txt)" -uroot DB-Name > /backupsDir/DB-Name_`date +%Y%m%d-%H:%M:%S`.sql
This is tested and known to work correctly in Ubuntu 20.04 LTS with mariadb-client.
I'm doing mine a different way, using Plink(Putty command line) to connect to remotehost, then the below command is in the plink file that runs on the remote server, then I use RSYNC from windows to get it and backup to an onprem NAS.
sudo mysqldump -u root --all-databases --events --routines --single-transaction > dump.sql
I have keys setup on the remote host and using PowerShell that's scheduled via task scheduler to run weekly.
what about --password=""
worked for me running on 5.1.51
mysqldump -h localhost -u <user> --password="<password>"
Definitely I think it would be better and safer to place the full cmd line in the root crontab , with credentails.
At least the crontab edit is restricred (readable) to someone who already knows the password.. so no worries to show it in plain text...
If needed more than a simple mysqldump... just place a bash script that accepts credentails as params and performs all amenities inside...
The bas file in simple
#!/bin/bash
mysqldump -u$1 -p$2 yourdbname > /your/path/save.sql
In the Crontab:
0 0 * * * bash /path/to/above/bash/file.sh root secretpwd 2>&1 /var/log/mycustomMysqlDump.log
You can specify the password on the command line as follows:
mysqldump -h <host> -u <user> -p<password> dumpfile
The options for mysqldump are Case Sensitive!