Inserting user defined variable in mysql CREATE USER - mysql

I would like to create a shell script to run in docker CLI and create a MySQL user with the host IP passed as a command line variable.
So with my script it would be ./create_user.sh 172.17.0.1
I tried starting with inserting variable only in the sql statements part and using something like this:
#!/bin/sh
docker exec -i atb-mariadb bash <<'EOF'
mysql -uroot -pmypass
set #ip='172.17.0.1';
CREATE USER 'exporter'##ip IDENTIFIED BY 'mypass';
GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'exporter'#'172.17.0.1';
GRANT SELECT ON performance_schema.* TO 'exporter'#'172.17.0.1';
SELECT user, host FROM mysql.user;
exit
EOF
This results in syntax error, along with some others i tried :
CREATE USER CONCAT_WS('exporter','#',#ip) IDENTIFIED BY 'mypass';
CREATE USER 'exporter'#CONCAT_WS('',#ip) IDENTIFIED BY 'mypass';
This is of course only the variable within the sql statements part of the script. Using a variable in the overall shell script and passing that into the sql bash is a problem that I have not even been able to come to yet.
Thanks in advance for any help!
UPDATED
I tried Raymond Nijland's solution and it worked for the sql variable part. However, trying to pass the variable value through the command line is still failing for the following script:
#!/bin/sh
echo script received $1
docker exec -e ipa=$1 -i atb-mariadb bash <<'EOF'
echo exec received $ipa
mysql -uroot -pmypass -e "
SET #ip='${ipa}';
SET #createUser = 'CONCAT("CREATE USER exporter#",#ip,"IDENTIFIED BY'mypass'")';
PREPARE smtpCreateUser FROM #createUser;
EXECUTE smtpCreateUser;";
exit
EOF
with the output
$ ./create_user.sh 172.18.0.5
script received 172.18.0.5
exec received 172.18.0.5
mysql Ver 15.1 Distrib 10.2.9-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Usage: mysql [OPTIONS] [database]
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf
The following groups are read: mysql client client-server client-mariadb
The following options may be given as the first argument:
--print-defaults Print the program argument list and exit.
......and so on
I understad the usual approach is to run a separate .sql script file with the -e handle but unfortunately bind-mounting this file into the default mariadb container or creating a custom image are both not possible appraoches given the current requirements.

You should be able to generate dynamic SQL statements with CONCAT, PREPARE and execute them.
Query
SET #ip = '172.17.0.1';
SET #createUser = CONCAT(
"CREATE USER exporter#",#ip, " IDENTIFIED BY 'mypass'"
);
PREPARE smtpCreateUser FROM #createUser;
EXECUTE smtpCreateUser;

You need to grab the variable from the shell before it can be used in the query. I think you are looking for something like (make sure to remove the quotes from EOF):
#!/bin/sh
docker exec -i atb-mariadb bash <<EOF
ip="${1:-127.0.0.1}"
echo mysql -uroot -pmypass
echo CREATE USER 'exporter'#'${ip}' IDENTIFIED BY 'mypass';
GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'exporter'#'172.17.0.1';
GRANT SELECT ON performance_schema.* TO 'exporter'#'172.17.0.1';
SELECT user, host FROM mysql.user;
exit
EOF

Related

How can I use an environment variable in the MySQL console

I can connect to the console as root using an environment variable:
mysql -u root -p${MYSQL_ROOT_PASSWORD}
I’d like to be able to use a different environment variable in a statement
CREATE USER ${MYSQL_USER} IDENTIFIED BY ${MYSQL_USER_PASSWORD};
Which obviously doesn’t work (or why would I be asking). Is there any way I can use an environment variable in the console?
I don't think there's any way to access environment variables from MySQL queries. But you can construct the MySQL query and substitute variables in the shell.
mysql -e "CREATE USER '{$MYSQL_USER}' IDENTIFIED BY '${MYSQL_USER_PASSWORD}'"
The shell will substitute the variables into the string before it's passed to the mysql command. For longer queries you can use a here-doc:
mysql <<EOF
CREATE USER '{$MYSQL_USER}'
IDENTIFIED BY '${MYSQL_USER_PASSWORD}'
EOF

How to give a variable of my script sh to my script SQL?

I'm looking for to pass a variable of my bash script, in my SQL query file and I can not.
Here is the latest version into my script.sh:
user = "USEREXAMPLE"
mysql –root -proot –h localhost -A -e "set #user=${user};" > "add.sql";
into my add.sql:
CREATE USER ', #user ,’#‘localhost’ IDENTIFIED BY ', #user ,';
Request desired after this :
CREATE USER USEREXEMPLE#localhost IDENTIFIED BY USEREXEMPLE;
Create your file like this:
#!/bin/bash
user="USEREXAMPLE"
echo "CREATE USER $user#localhost IDENTIFIED BY $user;" >add.sql
Then user add.sql in your mysql command.

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

sql statement in a bash script "command not found"

I've got a bash script that runs a series of sql statements:
#!/bin/bash
mysql -u root -p << QUERY_INPUT
CREATE DATABASE dba_first;
CREATE DATABASE dba_second;
CREATE DATABASE dba_third;
GRANT ALL PRIVILEGES ON `dba%`.* TO `dbuser`#`localhost`;
QUERY_INPUT
When I run the script, I get: ./quick.sh: line 20: dba%: command not found
Any suggestions please?
Answered by a nice person on IRC; have to escape the `
GRANT ALL PRIVILEGES ON \`dba%\`.* TO \`dbuser\`#\`localhost\`;

replacing sqlplus commands with mysql commands

i am trying to rewrite a script that is written in c-shell script to that uses sql plus command to get information from an oracle database but i am replacing it with mysql and i would like to replace all sqlplus syntax with mysql syntax. I am asking all the c-shell gurus to explain to me what this command means
set SQLPLUS=${ORACLE_HOME}/bin/sqlplus
set REPORT=${MYBD_HOME}/Scripts/report.sql
so somewhere along the line i invoke the sql plus command using the follwing
${SQLPLUS} ${MYDBUSER} # &{REPORT}
i am able to say i undertand what the right hand values mean ({ORACLE_HOME}/bin/sqlplus) is the path to where my sqplus command is located and thus i need it to invoke the command and the {REPORT=$(MYBD_HOME}/Scripts.report.sql) is the path where my sql script that is to be ran by invoking the sqplus command resides correct?
what i dont understand is what the set command is initializing this to. is SQLPLUS a variable so i dont have to type the path when i try to put it in my .csh script?
If so then all i need to do to run this script on a mysql database is simply set the SQLPLUS(problably change it to MYSQL) to point to the path where my msql exec is right
set MYSQL=${MYSQL_HOME}/bin/mysql
then just invoke mysql and run the sql statement
${MYSQL}${MYDBUSER}#${REPORT}
is this what i need to do ro tun the same .tsch script to get data from a mysql table?
You'll need something like this:
${MYSQL} -u $username -p$password -D $database < ${REPORT}
(The username and password are passed in differently to the mysql executable than they are passed to SQLPlus. You'll need to parse out the username and the password from ${MYDBUSER}. Likely, that contains a string such as "scott/tiger". The equivalent on the mysql command line client would be "-u scott -ptiger -D scott".
That # (at sign) is a SQLPlus thing; it tells SQLPLus to read input from the specified filename. The equivalent in mysql would be the source command, e.g.
${MYSQL} -u $username -p$password <_EOD!
use $database
source ${REPORT}
_EOD!
Also, your report.sql file likely includes spool and other SQLPLus specific commands. The mysql command line client is NOT ANYWHERE near as powerful a reporting tool as SQLPlus is.
Addendum:
Q: what exactly does the spool do?
The SQLPlus spool command directs output to a file. It's frequently used to create a log file from a SQLPLus session, and is also useful for creating report files.
set trimspool on
spool /tmp/file.lis
select 'foo' as foo from dual;
spool off
Q: Why can't i set the user name and passowrd to a variable and use that?
You could set a variable, the end result of the command line sent to the OS would be the same.
set MYDBUSER="-u username -ppassword -D database"
${MYSQL} ${MYDBUSER} <${REPORT}
Q:Seems like mysql is more verbose than sqlplus.
The mysql command line client takes unix-style options. These are equivalent:
mysql -u myusername -pmypassword -D mydatabase
mysql --user=myusername --password=mypassword --database=mydatabase