How can I execute an SQL command through a shell script so that I can make it automated?
I want to restore data I have collected in a SQL file using a shell script.
An important consideration for accessing mysql from a shell script used in cron, is that mysql looks at the logged in user to determine a .my.cnf to load.
That does not work with cron. It can also get confusing if you are using su/sudo as the logged in user might not be the user you are running as.
I use something like:
mysql --defaults-extra-file=/path/to/specific/.my.cnf -e 'SELECT something FROM sometable'
Just make sure that user and group ownership and permissions are set appropriately and tightly on the .my.cnf file.
You need to use the -p
flag to send a password. And it's tricky because you must have no space between -p
and the password.
$ mysql -h "server-name" -u "root" "-pXXXXXXXX" "database-name" < "filename.sql"
If you use a space after -p
it makes the mysql client prompt you interactively for the password, and then it interprets the next command argument as a database-name:
$ mysql -h "server-name" -u "root" -p "XXXXXXXX" "database-name" < "filename.sql"
Enter password: <you type it in here>
ERROR 1049 (42000): Unknown database 'XXXXXXXX'
Actually, I prefer to store the user and password in ~/.my.cnf so I don't have to put it on the command-line at all:
[client]
user = root
password = XXXXXXXX
Then:
$ mysql -h "server-name" "database-name" < "filename.sql"
Re your comment:
I run batch-mode mysql commands like the above on the command line and in shell scripts all the time. It's hard to diagnose what's wrong with your shell script, because you haven't shared the exact script or any error output. I suggest you edit your original question above and provide examples of what goes wrong.
Also when I'm troubleshooting a shell script I use the -x
flag so I can see how it's executing each command:
$ bash -x myscript.sh
I have written a shell script which will read data from properties file and then run mysql script on shell script. sharing this may help to others.
#!/bin/bash
PROPERTY_FILE=filename.properties
function getProperty {
PROP_KEY=$1
PROP_VALUE=`cat $PROPERTY_FILE | grep "$PROP_KEY" | cut -d'=' -f2`
echo $PROP_VALUE
}
echo "# Reading property from $PROPERTY_FILE"
DB_USER=$(getProperty "db.username")
DB_PASS=$(getProperty "db.password")
ROOT_LOC=$(getProperty "root.location")
echo $DB_USER
echo $DB_PASS
echo $ROOT_LOC
echo "Writing on DB ... "
mysql -u$DB_USER -p$DB_PASS dbname<<EOFMYSQL
update tablename set tablename.value_ = "$ROOT_LOC" where tablename.name_="Root directory location";
EOFMYSQL
echo "Writing root location($ROOT_LOC) is done ... "
counter=`mysql -u${DB_USER} -p${DB_PASS} dbname -e "select count(*) from tablename where tablename.name_='Root directory location' and tablename.value_ = '$ROOT_LOC';" | grep -v "count"`;
if [ "$counter" = "1" ]
then
echo "ROOT location updated"
fi
mysql -h "hostname" -u usr_name -pPASSWD "db_name" < sql_script_file
(use full path for sql_script_file
if needed)
If you want to redirect the out put to a file
mysql -h "hostname" -u usr_name -pPASSWD "db_name" < sql_script_file > out_file
All of the previous answers are great. If it is a simple, one line sql command you wish to run, you could also use the -e option.
mysql -h <host> -u<user> -p<password> database -e \
"SELECT * FROM blah WHERE foo='bar';"
You forgot -p
or --password=
(the latter is better readable):
mysql -h "$server_name" "--user=$user" "--password=$password" "--database=$database_name" < "filename.sql"
(The quotes are unnecessary if you are sure that your credentials/names do not contain space or shell-special characters.)
Note that the manpage, too, says that providing the credentials on the command line is insecure. So follow Bill's advice about my.cnf.