I need to grant privileges to a database from within a bash script. Some parameters are in the form of variables, say, the username and the password. The command in a mysql shell would look like this:
GRANT ALL ON *.* TO "$user"#localhost IDENTIFIED BY "$password";
...Except that $user and $password would be replaced by their values.
Is there a way to perform such a command from within a bash script?
Thank you!
There you go :)
#!/bin/bash
MYSQL=`which mysql`
EXPECTED_ARGS=3
Q1="USE $1;"
Q2="GRANT ALL ON *.* TO '$1'#'localhost' IDENTIFIED BY '$2';"
Q3="FLUSH PRIVILEGES;"
SQL="${Q1}${Q2}${Q3}"
if [ $# -ne $EXPECTED_ARGS ]
then
echo "Usage: $0 dbname dbuser dbpass"
exit $E_BADARGS
fi
$MYSQL -uroot -p -e "$SQL"
If we donĀ“t know the password we can get it with:
cat /etc/psa/.psa.shadow
So we can get into mysql without prompt password like:
mysql -uadmin -p`cat /etc/psa/.psa.shadow`
Related
I want to run MySQL query from bash script to create new user:
mysql -u root -p$dbpass -e "GRANT ALL PRIVILEGES ON appdb_${BUILD}.* TO appuser#localhost IDENTIFIED BY 'somepass'"
Where $BUILD variable is set to a number, for example 15, so final query should look like this:
mysql -u root -p$dbpass -e "GRANT ALL PRIVILEGES ON appdb_15.* TO appuser#localhost IDENTIFIED BY 'somepass'"
But... in directory where script is and is run there is a tar archive with same name as database, so query becomes like this:
mysql -u root -p$dbpass -e "GRANT ALL PRIVILEGES ON appdb_15.tar.gz TO appuser#localhost IDENTIFIED BY 'somepass'"
I guess this happens because there is a match, but changing file name is not an option. Moving script to other directory is not allowed too.
I tried to escape dot with backslashes (appdb_${BUILD}\.*) - nothing changed.
How I can fix this?
There is nothing wrong with your approach and it is working in my case. See below. Can you tell us what is the error that you are getting so that we can help you?
[root#cloud mysql]# ls
appdb_15.tar.gz test.sh
[root#cloud mysql]# cat test.sh
#!/bin/bash
BUILD=15
# First Method
mysql -u root -ptest -e "GRANT ALL PRIVILEGES ON appdb_${BUILD}.* TO appuser#localhost IDENTIFIED BY 'somepass';"
# Second Method
mysql -u root -ptest <<EOF
GRANT ALL PRIVILEGES ON appdb_${BUILD}.* TO appuser1#localhost IDENTIFIED BY 'somepass';
select user, host from mysql.user where user like 'appuser%';
EOF
[root#cloud mysql]# ./test.sh
user host
appuser localhost
appuser1 localhost
EDIT 1:
I forgot to mention that this is definitely not a bash issue.
EDIT 2: Changed the build variable to 15 from 5.
This is part of a Bash script, and the inside looks like this:
createdbcmd="docker exec $1 mysql -v -uroot -e \"GRANT ALL PRIVILEGES ON $dbname.* TO $2#$4 IDENTIFIED BY '$3'\""
echo $createdbcmd
$createdbcmd
the echo looks like this:
docker exec mysql_test_no mysql -v -uroot -e "GRANT ALL PRIVILEGES ON wordpress.* TO user#172.17.0.63 IDENTIFIED BY 'changeme'"
Running this exact command works just fine. via the bash-script it acts as if i'm just running 'mysql'
and i get the default help information with no error.
Try this way:
createdbcmd="docker exec $1 mysql -v -uroot -e \"GRANT ALL PRIVILEGES ON $dbname.* TO $2#$4 IDENTIFIED BY '$3'\""
echo $createdbcmd
eval $createdbcmd
Without the eval, the quoted expression is not interpreted correctly.
I'm trying to create a batch script that will create a database when executed. If the database is already existing, the script should echo that it already exists. I have it working on Linux, but it's apparently much more different on Windows.
Here is the script:
#echo off
SET dbname=1234
SET user=1234
SET password=1234
SET hostinfo=test3
SET RESULT="mysql -u root -ppassword --skip-column-names -e SHOW DATABASES LIKE '%dbname%'"
if %RESULT% == "%dbname%" (
echo "The database already exists. You can use the reinstall function instead."
) else (
mysql -h localhost -u root -ppassword -e "CREATE USER '%user%'#'%%'"
mysql -h localhost -u root -ppassword -e "SET PASSWORD FOR '%user%'#'%%' = PASSWORD('%password%')"
mysql -h localhost -u root -ppassword -e "GRANT USAGE ON * . * TO '%user%'#'%%' IDENTIFIED BY '%password%' WITH MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0"
mysql -h localhost -u root -ppassword -e "CREATE DATABASE IF NOT EXISTS `%dbname%`"
mysql -h localhost -u root -ppassword -e "GRANT ALL PRIVILEGES ON `%dbname%` . * TO '%user%'#'%%'"
echo A new MySQL database has been created for you.
echo Username: %user%
echo Password: %password%
echo Database: %dbname%
echo Host: %hostinfo%:3306
)
The output is just the following:
Warning: Using a password on the command line interface can be insecure.
ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for '1234'#'%'
Warning: Using a password on the command line interface can be insecure.
Warning: Using a password on the command line interface can be insecure.
Warning: Using a password on the command line interface can be insecure.
Warning: Using a password on the command line interface can be insecure.
A new MySQL database has been created for you.
Username: 1234
Password: 1234
Database: 1234
Host: test3:3306
How would I do this? It doesn't seem like the if else statement is working correctly...
Kind regards,
Dennis
please before if statement 'echo %RESULT% and %dbname%' it will help you to know why this problem happens
I'm suggesting to change the if to be if "%RESULT%" == "%dbname%"
The result variable include the string for the command but not executed .. so you have to execute it and set the out put into it.
Check this:
#echo off
SET dbname=1234
SET user=1234
SET password=1234
SET hostinfo=test3
SET RESULT="mysql -u root -ppassword --skip-column-names -e SHOW DATABASES LIKE '%dbname%'"
for /f "delims=" %%i in ('%RESULT%') do set RESULT=%%i
if %RESULT% == "%dbname%" (
echo "The database already exists. You can use the reinstall function instead."
) else (
mysql -h localhost -u root -ppassword -e "CREATE USER '%user%'#'%%'"
mysql -h localhost -u root -ppassword -e "SET PASSWORD FOR '%user%'#'%%' = PASSWORD('%password%')"
mysql -h localhost -u root -ppassword -e "GRANT USAGE ON * . * TO '%user%'#'%%' IDENTIFIED BY '%password%' WITH MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0"
mysql -h localhost -u root -ppassword -e "CREATE DATABASE IF NOT EXISTS `%dbname%`"
mysql -h localhost -u root -ppassword -e "GRANT ALL PRIVILEGES ON `%dbname%` . * TO '%user%'#'%%'"
echo A new MySQL database has been created for you.
echo Username: %user%
echo Password: %password%
echo Database: %dbname%
echo Host: %hostinfo%:3306
)
I did a similar batch before check this post
http://muhammadhamed.blogspot.com/2013/01/install-mysql-as-windows-service-from.html
I hope this could help!
In a simple script like this one:
set -x
# Check if db exists, if not we make it, make user, give privileges
if ! mysql -u root -p -e "use $db" 2>/dev/null; then
c1="CREATE DATABASE $db"
c2="GRANT ALL PRIVILEGES ON ${db}.* to '$username'#'localhost' IDENTIFIED BY '$password'"
c3="FLUSH PRIVILEGES"
mysql -u root -p -e "$c1; $c2; $c3"
else
echo 'DATABASE ExISTS, ABORTING'; exit $DB_EXISTS
fi
I am asked each time, bash sees mysql command, for my root credentials.
Is there a way to avoid that, so that once entered the root password, all
additional mysql commands execute seamlessly?
Try looking into adding password to ~/.my.cnf
[client]
user = root
password = XXXXXXXX
Check out :
How to execute a MySQL command from a shell script?
Specifying the --password argument
mysql -u root --password=my_mysql_pass db_name
Safer using a bash variable
mysql -u root --password=$MYSQL_PASS db_name
Question Rewritten:
HOMEDIR="ftpuser"
REMOTEIP="1.1.1.1"
MYSQLPASS="password"
Q1="DROP USER "$HOMEDIR"_shop;"
Q2="DROP DATABASE "$HOMEDIR"_shop;"
Q3="CREATE DATABASE IF NOT EXISTS "$HOMEDIR"_shop;"
Q4="GRANT ALL ON "$HOMEDIR"_shop TO '"$HOMEDIR"_shop'#'localhost' IDENTIFIED BY '$MYSQLPASS';"
Q5="GRANT ALL ON "$HOMEDIR"_shop TO '"$HOMEDIR"_shop'#'anotherip' IDENTIFIED BY '$MYSQLPASS';"
# Need to grant permissions from another server as well
Q6="FLUSH PRIVILEGES;"
SQL="${Q1}${Q2}${Q3}${Q4}${Q5}${Q6}"
echo $SQL
echo " "
ssh -p 8899 root#$REMOTEIP "mysql -u root -p "$SQL""
I then run:
/root/testing/migratesite.sh
And get:
bash: DROP: command not found
bash: CREATE: command not found
bash: GRANT: command not found
bash: GRANT: command not found
bash: FLUSH: command not found
What am I missing?
You are missing quotes and a proper mysql client command line:
ssh -p 8899 root#$REMOTEIP "mysql -u root -p -e \"$SQL\""
You need to escape the quotes around the $SQL variable so they get passed to the remote shell, else they get interpreted by the local shell (that's why you get DROP: command not found, the semi colon is interpreted by the shell.) Also, to have the mysql client to execute a command you have to pass the -e command line option.
Did you try this:
ssh -p 8899 root#$REMOTEIP "echo \"$SQL\" | mysql -u root --password=$SQL_PASS"