mysqldump access denied when being used in bash script - mysql

I am trying to create a bash script that uses mysqldump to create a backup of the database that is specified as parameter. However mysqldump fails with an access denied error. Using the same command directly (copying it to the shell an executing it) works without any problem.
#!/bin/bash
# ... use parameters to get db name and password
# build the mysqldump command and execute it...
command="mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u ${database} -p'${pw}' --extended-insert ${database} | gzip > ${path}"
echo "$command"
echo ""
$command
This gives me the following output:
$ ./dbbak DBUSER DBNAME PASSWORD
mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u DBUSER -p'PASSWORD' --extended-insert DBNAME | gzip > /path/to/backup/backup.sql.gz
Warning: Using a password on the command line interface can be insecure.
-- Connecting to 127.0.0.3...
mysqldump: Got error: 1045: Access denied for user 'DBUSER'#'localhost' (using password: YES) when trying to connect
As said before: When I copy the echoed mysqldump command and execute it directly, the backup works just fine.
What is the problem here? Since the command is executed correctly when being used manually all parameters (password, username, etc.) seem to be correct. Additionally the bash script is executed with the same user account as the manual command.
So why does the manual execution work while the bash script fails?
EDIT:
As Jens pointed out in his comment, removing the quotes from the password will solve the problem. ...-p${pw}... will work, BUT this will also lead to a new problem, if the password contains special characters like $ < > ...
I assume that the problem with the quotes is how bash parses the string. Meanwhile I found some docs that say, that it is a bad habit to store commands in variables and execute them. Instead one should execute commands directly. However the following does not work as well:
result=$(mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u ${database} -p'${pw}' --extended-insert ${database} | gzip > ${path})
When executing this with bash -x dbbak the output shows the problem:
...
++ mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u DBUSER '-p'\''DBPASS'\''' --extended-insert DBNAME
While I do understand why the quotes around DBPASS are added ('DBPASS' --> \''DBPASS'\'), I do not understand why there are also quotes around-p`.
How do I get rid of these quotes when executing the command?

You can either:
store the password in an environment variable MYSQL_PWD
store the password in a plain-text file .my.cnf which you need to put into
the home directory of the user that executes the script
use the mysql_config_editor utility to store the password in an encrypted
file
The first one is the easiest to use/implement but obviously the least secure.
I recommend to take a look at the documentation where all the possibilities are described. ;)

Configure it by .cnf file and provide it in --defaults-file
mysqldump --defaults-file=~/my_mysql.cnf db table > table.sql
In ~/my_msyql.cnf
[mysqldump]
user=user_name
password=my_password
host=my_host
This is also safe if you version this. You can save my_mysql.cnf differently per environment.

To remove the single quotes around the password solved for me.

Related

Which username and password does mysqldump expect?

I'm trying to make a copy of my website's database, so that I can download it and import it into wamp for local testing.
Here is what I'm entering in Putty:
mysqldump -u my_database_username -p dataname_db.sql --single-transaction --quick --lock-tables=false > dataname_db_local-$(date +%F).sql && gzip dataname_db_local.sql
No matter what combo of user and pass I use, I get this error
Got error: 1044: "Access denied for user to database when selecting the database
It wants the MySQL user that has full privileges to that database, right? ie the same credentials as what I use to connect to the database in a new MySQLi() command in php, right?
I read that sometimes passwords with special characters aren't allowed, so I made a new user, full priveleges, for that database with a plain alphanumeric pass, but it's still not accepted.
I then thought maybe it wants the same username and pass as what I use to connect to my server via Putty, but that didn't work. Neither did -u root with the server password.
Can someone please clarify exactly which username it wants?
Thank you
Yes, you are right, mysqldump requires exactly the same username and password as what you use to connect to the database in a new MySQLi() command in php.
Make sure your account has Lock_Table privilege.
If it still didn't work, try to pass the –-single-transaction option to mysqldump:
mysqldump --single-transaction -u db_username -p DBNAME > backup.sql
Notice that there is a syntax problem, you should select your DB at last of mysqldump statement:
mysqldump [options] db_name [tbl_name ...] > filename.sql
Reference: [1] , [2]

MySql 1045 When using --defaults-file

I am having a strange issue. I have MySql running on RHEL. I can logon to MySql with
mysql -uroot -pmyPassword
and it works fine. Also, when I try to execute a query from a .sh script as below it works fine
mysql --user=root --password=myPassword --host=localhost --port=3306 -se "SELECT 1 as testConnect" 2>&1>> $OUTPUT
But when I store the userid and password in a msql.conf file as below
[clientroot]
user=root
password=myPassword
and then change the line in the script as below
mysql --defaults-file=msql.conf --defaults-group-suffix=root -hlocalhost -P3306 -se "SELECT 1 as testConnect" 2>&1>> $OUTPUT
When I run it, I get the error:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
I am running the script with sudo and the config file is at the same directory as the script
I have permission 0600 on the config file.
How do I make this work?
It worked for me, but it was a bit of a 'tricky' fix that isn't shown in the actual documentation. All you have to do is change
[clientroot]
user=root
password=myPassword
to
[clientroot]
user="root"
password="myPassword"
Basically just add the double quotes.
Then running your command:
mysql --defaults-file=msql.conf --defaults-group-suffix=root -hlocalhost -P3306 -se
"SELECT 1 as testConnect" 2>&1>> $OUTPUT
Should work (it worked for me).
I discovered this by looking through an obscure part of the documentation on something almost unrelated, so I don't blame everyone for missing it.
Options files are not meant for auto-login credentials.
Try this:
export MYSQL_PWD=myPassword
And try to connect using the root user.
Note that this approach is "insecure", but so is the basic idea of what you're trying to do.
When your goal is to not use the password in scripts or on command line, may I suggest a different approach?
You can create a file with the login credentials encrypted and use that for logging in.
Here's an example:
Create the file with
mysql_config_editor --set-login-path=local --host=localhost --user=localuser --password
This creates the file ~/.mylogin.cnf. You can now login with
mysql --login-path=local
local is a name you can specify, btw.
Here's another plus: You can also create different files for different projects. For example, I sometimes create files for certain scripts. I put the .mylogin.cnf in the same folder as the script and use it like this in the script:
RESULT=($(MYSQL_TEST_LOGIN_FILE=./.mylogin.cnf mysql --login-path=$HOST -B --skip-column-names -e "SELECT whatever FROM whatever"))
Read more about mysql_config_editor here.

Run mysql commands in bash script without logging in or adding -u root to every command

I'm writing a bash script to do some db stuff. New to MySQL. I'm on Mac and have MySQL installed via homebrew.
Am using username "root" right now and there isn't a pw set. I included the pw syntax below just to help others out that may have a pw.
My goal is to have mysql commands be as "clean" as possible in my bash script
Not a hige deal, but would like to do this if possible.
Example
# If I can do it without logging in (*ideal)
mysql CREATE DATABASE dbname;
# Or by logging in with - mysql -u root -pPassword
CREATE DATABASE dbname;
# Instead of
mysql -u root -pPassword -e"CREATE DATABASE dbname";
Tried to simplify it. I have a handful of things I gotta do, so would rather keep my code cleaner if possible. I tried logging in with the bash script, but the script stopped once logged into MySQL and didn't run any commands.
Another option I was considering (but don't really like) would be just to keep username and pw string in a var and call it for every commmand like so
# Set the login string variable
login_details="-u root -p password -e"
# example command
mysql $login_details"CREATE DATABASE dbname";
So any ideas?
Write a new bash script file and run this file after putting all your commands into it. Don't forget to give right username and password in your bash script.
For bash script:
#!/bin/bash
mysql -u root -pSeCrEt << EOF
use mysql;
show tables;
EOF
If you want to run single mysql command.
mysql -u [user] -p[pass] -e "[mysql commands]"
Example:
mysql -h 192.168.1.10 -u root -pSeCrEt -e "show databases"
To execute multiple mysql commands:
mysql -u $user -p$passsword -Bse "command1;command2;....;commandn"
Note: -B is for batch, print results using tab as the column separator, with each row on a new line. With this option, mysql does not use the history file. Batch mode results in nontabular output format and escaping of special characters. -s is silent mode. Produce less output. -e is to execute the statement and quit

bash script command to inject a schema.sql into mysql db

i found this code but do not quite understand what the command is doing.
sudo -u test-user mysql -U test_traffic traffic < ./phoenix/data/sql/lib.model.schema.sql
i know the last part is using lib.model.schema.sql to create the tables and fields
the first part i dont quite understand: sudo -u test-user mysql -U test_traffic traffic
i know the command sudo and mysql
please explain?
thanks
Let's look at it bit by bit. Firstly the format
sudo -u username command
is an instruction to run command (which might be simple or complex) as the user username. So in your example, you are running the mysql command as the user test-user. You should note that this includes all the parameters to the mysql command - that's the entire rest of the line.
The command
mysql -U test_traffic traffic < ./phoenix/data/sql/lib.model.schema.sql
appears corrupt (certainly running it on 5.0.51a fails). It would make sense if the -U was a -u which would indicate that that the command was to be executed for mysql user test_traffic. If it was a -u you would then have an instruction to import the sql file into the traffic database.
So the combined instruction says, import the lib.model.schema.sql file into the database test_traffic using the mysql user test_traffic and executing the entire command as if you were logged-in as the user test-user.
Try Below steps for mysql:
mysql > -h hostname -u username -p password
mysql > use databasename;
mysql > source path/to/scriptfile
If you want to inject theschema.sql file into your database, with a shell script, simply use :
mysql -h [host] -u [username] -p[password] -D [database] < your_file
If you want to dynamicly tell which file should be loaded, replace your_file by $1 and pass the name of the file as an argument to your script.
Take care also to the -p option. There is no space between the -p and your password.

How to run SQL script in MySQL?

I want to execute a text file containing SQL queries, in MySQL.
I tried to run source /Desktop/test.sql and received the error:
mysql> . \home\sivakumar\Desktop\test.sql ERROR: Failed to open file
'\home\sivakumar\Desktop\test.sql', error: 2
Any idea on what I am doing wrong?
If you’re at the MySQL command line mysql> you have to declare the SQL file as source.
mysql> source \home\user\Desktop\test.sql;
You have quite a lot of options:
use the MySQL command line client: mysql -h hostname -u user database < path/to/test.sql
Install the MySQL GUI tools and open your SQL file, then execute it
Use phpmysql if the database is available via your webserver
you can execute mysql statements that have been written in a text file using the following command:
mysql -u yourusername -p yourpassword yourdatabase < text_file
if your database has not been created yet, log into your mysql first using:
mysql -u yourusername -p yourpassword
then:
mysql>CREATE DATABASE a_new_database_name
then:
mysql -u yourusername -p yourpassword a_new_database_name < text_file
that should do it!
More info here: http://dev.mysql.com/doc/refman/5.0/en/mysql-batch-commands.html
My favorite option to do that will be:
mysql --user="username" --database="databasename" --password="yourpassword" < "filepath"
I use it this way because when you string it with "" you avoiding wrong path and mistakes with spaces and - and probably more problems with chars that I did not encounter with.
With #elcuco comment I suggest using this command with [space] before so it tell bash to ignore saving it in history, this will work out of the box in most bash.
in case it still saving your command in history please view the following solutions:
Execute command without keeping it in history
extra security edit
Just in case you want to be extra safe you can use the following command and enter the password in the command line input:
mysql --user="username" --database="databasename" -p < "filepath"
All the top answers are good. But just in case someone wants to run the query from a text file on a remote server AND save results to a file (instead of showing on console), you can do this:
mysql -u yourusername -p yourpassword yourdatabase < query_file > results_file
Hope this helps someone.
I came here searching for this answer as well, and here is what I found works the best for me: Note I am using Ubuntu 16.x.x
Access mysql using:
mysql -u <your_user> - p
At the mysql prompt, enter:
source file_name.sql
Hope this helps.
Give the path of .sql file as:
source c:/dump/SQL/file_name.sql;
mysql> source C:\Users\admin\Desktop\fn_Split.sql
Do not specify single quotes.
If the above command is not working, copy the file to c: drive and try again.
as shown below,
mysql> source C:\fn_Split.sql
instead of redirection I would do the following
mysql -h <hostname> -u <username> --password=<password> -D <database> -e 'source <path-to-sql-file>'
This will execute the file path-to-sql-file
Never is a good practice to pass the password argument directly from the command line, it is saved in the ~/.bash_history file and can be accessible from other applications.
Use this instead:
mysql -u user --host host --port 9999 database_name < /scripts/script.sql -p
Enter password:
mysql -uusername -ppassword database-name < file.sql
So many ways to do it.
From Workbench: File > Run SQL Script -- then follow prompts
From Windows Command Line:
Option 1: mysql -u usr -p
mysql> source file_path.sql
Option 2: mysql -u usr -p '-e source file_path.sql'
Option 3: mysql -u usr -p < file_path.sql
Option 4: put multiple 'source' statements inside of file_path.sql (I do this to drop and recreate schemas/databases which requires multiple files to be run)
mysql -u usr -p < file_path.sql
If you get errors from the command line, make sure you have previously run
cd {!!>>mysqld.exe home directory here<<!!}
mysqld.exe --initialize
This must be run from within the mysqld.exe directory, hence the CD.
Hope this is helpful and not just redundant.
From linux 14.04 to MySql 5.7, using cat command piped with mysql login:
cat /Desktop/test.sql | sudo mysql -uroot -p
You can use this method for many MySQL commands to execute directly from Shell. Eg:
echo "USE my_db; SHOW tables;" | sudo mysql -uroot -p
Make sure you separate your commands with semicolon (';').
I didn't see this approach in the answers above and thought it is a good contribution.
Very likely, you just need to change the slash/blackslash:
from
\home\sivakumar\Desktop\test.sql
to
/home/sivakumar/Desktop/test.sql
So the command would be:
source /home/sivakumar/Desktop/test.sql
use the following from mysql command prompt-
source \\home\\user\\Desktop\\test.sql;
Use no quotation. Even if the path contains space(' ') use no quotation at all.
Since mysql -u yourusername -p yourpassword yourdatabase < text_file did not work on a remote server (Amazon's EC2)...
Make sure that the Database is created first.
Then:
mysql --host=localhost --user=your_username --password=your_password your_database_name < pathTofilename.sql
For future reference, I've found this to work vs the aforementioned methods, under Windows in your msql console:
mysql>>source c://path_to_file//path_to_file//file_name.sql;
If your root drive isn't called "c" then just interchange with what your drive is called. First try backslashes, if they dont work, try the forward slash. If they also don't work, ensure you have your full file path, the .sql extension on the file name, and if your version insists on semi-colons, ensure it's there and try again.
If you are here LOOKING FOR A DRUPAL ENVIRONMENT
You can run with drush command on your project directory
drush sqlc
If you are trying this command :
mysql -u root -proot -D database < /path/to/script.sql
You may get an error like this : if you have special characters, mainly '`'
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/path/to/script.sql' at line 1
So I would suggest to use a command like this :
echo "source /path/to/script.sql" | mysql -u root -proot -D database
This command will execute source /path/to/script.sql once connected to the server, which execute your script.
I had this error, and tried all the advice i could get to no avail.
Finally, the problem was that my folder had a space in the folder name which appearing as a forward-slash in the folder path, once i found and removed it, it worked fine.
I use Bash's Here Strings for an instant SQL execution:
mysql -uroot -p <<<"select date(now())"
https://www.gnu.org/software/bash/manual/html_node/Redirections.html#Here-Strings