Special chars issue while granting priviliges on mysql database - mysql

I came across with an issue while I was trying to grant privileges to a database for a mysql user via t. I think it's because of the special chars in the database name.
This one is working:
/usr/bin/mysql -uroot -pXz5eaCqwvsT0pAr0gsf0tg1a -e "GRANT ALL PRIVILEGES ON dev_52000_nycny.* TO 'wp_j-5-1-5_nycny'#localhost"
That one is not working:
/usr/bin/mysql -uroot -pXz5eaCqwvsT0pAr0gsf0tg1a -e "GRANT ALL PRIVILEGES ON dev_j-5-1-5_nycny.* TO 'wp_j-5-1-5_nycny'#localhost"
I have tried few combinations but no luck:
/usr/bin/mysql -uroot -pXz5eaCqwvsT0pAr0gsf0tg1a -e "GRANT ALL PRIVILEGES ON 'dev_j-5-1-5_nycny'.* TO 'wp_j-5-1-5_nycny'#localhost"
/usr/bin/mysql -uroot -pXz5eaCqwvsT0pAr0gsf0tg1a -e "GRANT ALL PRIVILEGES ON dev_j\-5\-1\-5_nycny.* TO 'wp_j-5-1-5_nycny'#localhost"
/usr/bin/mysql -uroot -pXz5eaCqwvsT0pAr0gsf0tg1a -e "GRANT ALL PRIVILEGES ON 'dev_j\-5\-1\-5_nycny'.* TO 'wp_j-5-1-5_nycny'#localhost"
What should I do ?

MySQL uses backticks to quote database, table, and column names that contain special characters. See When to use single quotes, double quotes, and backticks in MySQL
/usr/bin/mysql -uroot -pXz5eaCqwvsT0pAr0gsf0tg1a -e 'GRANT ALL PRIVILEGES ON `dev_j-5-1-5_nycny`.* TO "wp_j-5-1-5_nycny"#localhost`
Make sure you use single quotes around the -e argument, because backticks have special meaning to the shell when they're inside double quoted strings. I also changed the quotes around the username to double quotes to accomodate using single quotes around the whole query.

Related

create limit character for mysql user in bash script

I have created a bash script to create a MySQL database and user.
The username is my domain with dots replaced by _ (example_com). But the user field length limit is 16 characters.
Ex:
PASS="$(openssl rand -base64 12)"
DBNAME=${DOMAIN//[^a-zA-Z0-9]/_}
mysql -uroot -p${rootpasswd} -e "CREATE DATABASE ${DBNAME} /*\!40100 DEFAULT CHARACTER SET utf8 */;"
mysql -uroot -p${rootpasswd} -e "CREATE USER '${DBNAME}'#'localhost' IDENTIFIED BY '$PASS';"
mysql -uroot -p${rootpasswd} -e "GRANT ALL PRIVILEGES ON ${DBNAME}.* TO '${DBNAME}'#'localhost';"
mysql -uroot -p${rootpasswd} -e "FLUSH PRIVILEGES;"
How can I ensure the 16 characters limit is respected before sending the query to the database?
You have to cut the DBNAME value to the max desired length like this:
SHORT_DBNAME=${DBNAME:0:16}
Ex:
DBNAME=0123456789abcdefghijklmnop
SHORT_DBNAME=${DBNAME:0:16}
echo $SHORT_DBNAME
Will return 0123456789abcdef
Now you have to be careful that the first 16 chars combination is unique. If the difference is past the 16th character, if you try to create two users, names will be the same.

Excluding tables from "show tables" in a scripted mysqldump

I would like to update the following bash script, which individually dumps each table in a given schema:
for t in $(mysql -NBA -h db_host -u db_user -pdb_pass db_name -e 'show tables')
do
mysqldump -h db_host -u db_user -pdb_pass db_name $t > db_name.$t.sql
to exclude some tables that do not need to be picked up by this script. This is what I mean:
for t in $(mysql -NBA -h db_host -u db_user -pdb_pass db_name -e 'show tables where `Tables_in_db_name` not like 'table1' and `Tables_in_db_name` not like 'table2'')
do
mysqldump -h db_host -u db_user -pdb_pass db_name $t > db_name.$t.sql
The sql is fine in itself, but I can't get it to run inside the -e command. Obviously in this example, the problem is the -e command's opening and closing apostrophes. I have tried:
Using quotes instead of apostrophes. ie -e "show tables where etc"
Using slashes on the internal apostrophes. ie \'table1\'
With no success. Does anybody know how to accommodate apostrophes and back ticks within these confines?
Thank you.
The SQL is fine in itself, but I can't get it to run inside the -e command. Obviously in this example, the problem is the -e command's opening and closing apostrophes.
Right. I assume it will be necessary to escape the backticks. After a short test it seems that
mysql -NBA -h ${DB_HOST} -u "${DB_USER}" -p" ${DB_PASS}" ${DB_NAME} -e "SHOW TABLES WHERE \`Tables_in_${DB_NAME}\` NOT LIKE 'table%'"
is working.

How can I escape backticks in gnu make makefile

I have this make file:
createuser:
$(MYSQL) -e " grant SELECT, USAGE on `app\_%`.* to 'user.name'#'%' IDENTIFIED BY '$(USER_PASS)'" && \
$(MYSQL) -e "FLUSH PRIVILEGES;"
This command works fine if I execute it directly in a MySQL query window, but I want to execute it from terminal.
You don't need FLUSH PRIVILEGES with GRANT or CREATE USER
statements
For future compatibility - CREATE USER [IF NOT EXISTS]
before doing the GRANT
Within a Makefile you can escape using \
before both backticks.

How to disable dot replacement in bash?

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.

howto to create mysql database from fabric dynamically

Is it possible to create mysql database from fabric dynamically.
This seems like it gets stuck at the password prompt
run('mysql -u %s -p %s -h %s ' % (env.mysqluser, env.mysqlpassword, env.mysqlhost), pty=True)
run('CREATE DATABASE %s; ' % (dataname), pty=True)
run('exit', pty=True)
There's a better way of doing this using mysqladmin:
run('mysqladmin -u %s -p%s create %s' % (user, password, dbname))
Try instead
run('echo "CREATE DATABASE %s;"|mysql --batch --user=%s --password=%s --host=%s' % (dataname, env.mysqluser, env.mysqlpassword, env.mysqlhost), pty=True)
I use the following one liner via command line
mysql -uroot -prootpassword -e "CREATE DATABASE dbname";
key is the -e switch.
if you like to have bash script with variables in db/user/pass and run it as ./myscript then
#!/bin/bash
DB="mydb"
USER="user1"
PASS="pass_bla"
mysql -uroot -prootpassword -e "CREATE DATABASE $DB CHARACTER SET utf8 COLLATE utf8_general_ci";
mysql -uroot -prootpassword -e "CREATE USER $USER#'127.0.0.1' IDENTIFIED BY '$PASS'";
mysql -uroot -prootpassword -e "GRANT SELECT, INSERT, UPDATE ON $DB.* TO '$USER'#'127.0.0.1'";