create limit character for mysql user in bash script - mysql

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.

Related

Receiving 'ERROR 1046 (3D000) at line 1: No database selected' when executing linux bash script

I'm trying to automate the creation of a mysql user with a database and table using Linux bash, but receiving ERROR 1046.
I've looked at various tutorials online, including this website, and from what I can see, my script looks correct!
If i log in to mysql via the command line and run these commands manually, it works!
But if i run the exact same commands in a bash script, it fails. (name of user/db replaced with $1 variable)
Posting this as a last resort as all the posts i have found referring to this error say to use 'use databasename;' but i already do that in the script.
#Code to create mysql user with db and table in linux bash.
#to run: ./createmysqldb Testuser1 TestPass1
$1 = Testuser1
$2 = TestPass1
...
mysql -u$user -p$password -e "create user '$1'#'%' identified by '$2';"
mysql -u$user -p$password -e "create database $1_DB;"
mysql -u$user -p$password -e "use $1_DB;"
mysql -u$user -p$password -e "CREATE TABLE persons (id int, name varchar(20), surname varchar(20));"
mysql -u$user -p$password -e "GRANT ALL PRIVILEGES ON $1_DB.* TO '$1'#'%';"
mysql -u$user -p$password -e "flush privileges;"
...
Manually tested this code successfully, so i know it works, not sure if the variables and the use $1_DB; is being executed correctly, I expect a new user to be created, with a database containing a persons table.

Search for specific string/pattern in MySQL Database from Terminal/SSH/Commandline

I have a Magento database in which I want to search for a particular string/pattern.
But the database's size is too large so I cannot export the database to .sql file and then search into that file(editor even Geany crashes opening such large files).
So how can I do a search the database for a perfect match of [string/pattern] and display fulltext information as result, through only using command-line and MySQL Database credentials ?
I tried below command, but it requires username to be given as -u[USERNAME], also it doesn't display full query or result in terminal window.
mysqldump -p[PASSWORD] [DATABASE] --extended=FALSE | grep [pattern] | less -S
Anyone have any solutions for this ?
You can first log into MySQL CLI as especified in http://dev.mysql.com/doc/refman/5.7/en/connecting.html
mysql --host=localhost --user=myname --password=mypass mydb
So, you can use a query command to find your pattern. If you know the table you want to search such as the column it make the thinks easy. The SELECT statement is like this:
SELECT column FROM table WHERE column LIKE '%pattern%';
http://dev.mysql.com/doc/en/select.html
If you don't know the table's name, you can list all and try to find by the meaning.
SHOW TABLES;
Edited with better code
You didn't say if this was a one off or not but this will check all tables in a schema for a value.
First in your home directory set up a file named .my.cnf with the following contents and change its permissions to 700 (Replace [USERNAME] and [PASSWORD] with your username and password.
[client]
user=[USERNAME]
password="[PASSWORD]"
Then execute the following (Replacing [DATABASE] and [CHECKSTRING] with your database and the check string)
mysql [DATABASE] --silent -N -e "show tables;"|while read table; do mysql [DATABASE] --silent -N -e "select * from ${table};"|while read line;do if [[ "${line}" == *"[CHECKSTRING]"* ]]; then echo "${table}***${line}";fi;done;done
If checking for 51584 the result would be something like
test_table***551584,'column 2 value','column 3 value'
test_table5***'column 1 value',251584,'column 3 value'
If you want to know which column had the value then select from INFORMATION_SCHEMA.COLUMNS and add another nest.
mysql [DATABASE] --silent -N -e "show tables;"|while read table; do mysql [DATABASE] --silent -N -e "select column_name from information_schema.columns where table_schema='[DATABASE]' and table_name = '${table}';"|while read column; do mysql [DATABASE] --silent -N -e "select ${column} from ${table};"|while read line;do if [[ "${line}" == *"[CHECKSTRING]"* ]]; then echo "${table}***${column}***${line}";fi;done;done;done
If checking for 51584 the result would be something like
test_table***column1***551584
test_table5***column2***251584
First of all you need to login into database with correct username and password by below command.
sudo mysql -u root -p
then check the database in which you want to operate operation.
eg.
SHOW DATABASES;
USE Test;
now your database is ready for operation through terminal. Here I assume my database name is "Test".
Now for String/pattern matching use command as below or follow the link http://www.mysqltutorial.org/mysql-regular-expression-regexp.aspx.
SELECT
column_list
FROM
table_name
WHERE
string_column REGEXP pattern;

A better way to execute multiple MySQL commands using shell script

I would like to write a *.sh script to execute multiple MySQL commands.
Currently, what I can do is something like the following
mysql -h$host -u$user -p$password -e "drop database $dbname;"
mysql -h$host -u$user -p$password -e "create database $dbname;"
mysql -h$host -u$user -p$password -e "another MySQL command"
...
Is there a way to avoid typing mysql -h$host -u$user -p$password -e every time I want to execute a MySQL command?
I think you can execute MySQL statements from a text file, for example
here is the cmds.txt file which contains MySQL commands:
select colA from TableA;
select colB from TableB;
select colC from TableC;
To execute them using shell script, type
mysql -h$host -u$user -p$password db_dbname < cmds.txt
This way, you separate your MySQL commands from your shell script.
You may want your script to display progress information to you. For this you can invoke mysql with "--verbose" option.
For more information, see https://dev.mysql.com/doc/refman/5.6/en/mysql-batch-commands.html
You can use a single multiquery:
mysql -h$host -u$user -p$password -e "drop database $dbname;create database $dbname;another MySQL command;"
Simply write all your queries seperated by ;. They will be run one after the other.
Note that you can also use a HERE doc to have the queries within the same script:
mysql -h$host -u$user -p$password db_dbname <<'EOF'
select colA from TableA;
select colB from TableB;
select colC from TableC;
EOF
Note that I've used 'EOF' rather than EOF in the first line in order to prevent the contents of the script to disable parameter substitution (especially the ` can be problematic)
Also note that there should not be any whitespace before the final EOF (except if you use <<- rather than << -- in that case leading tab characters are stripped):
mysql -h$host -u$user -p$password db_dbname <<- 'EOF'
↠select colA from TableA;
↠select colB from TableB;
↠select colC from TableC;
↠EOF
(Replace the ↠ with a tab character).
For more info on the HERE doc syntax, see the bash documentation.
There are several ways, in linux you have:
From the mysql cli:
mysql> source mycmds.sql
Using Pipes:
echo "SELECT ..; INSERT ..;" | mysql ...
Executing commands from a file using pipes or redirection:
cat file.sql | mysql ... OR mysql .. < file.sql
Different from other answers that reduce repetition, but
there are ways to reduce options(user, host ... -u, -p, -h ...) from each line command
2 ways i know.
1. use my.cnf file
you can store your user information in option files (e.g ~/.my.cnf or etc)
[client]
user=your_username
password=your_password
# database=database_name
then you can just run mysql command with one option -e and query
mysql -e "drop database $dbname;"
mysql -e "create database $dbname;"
mysql -e "another MySQL command"
2. use mysql_config_editor
you can save login informations with mysql_config_editor
mysql_config_editor set --login-path=mypath1 --host=localhost --user=root --password
then run command just with login-path option
mysql --login-path=mypath1 -e "drop database $dbname;"
mysql --login-path=mypath1 -e "create database $dbname;"
mysql --login-path=mypath1 -e "another MySQL command"

unable to connect the mysql database using shell script

Am facing problem to connect the MySQL DB from shell script. Please find the below snippet i have written for connecting the MySQL data base. please suggest on this.
My shell Script:
#!bin/bash
Query="select * from Main"
MySQL -u root -p '!!root!!' -e kpi << EOF
$Query;
EOF
Please check the above code and suggest me how to connect the DB.
I think it should be
-pThePassword
So you should delete the space between -p and the pass. Also you should not use an apostrophe (except it is part of the pass itself. Use a backslash to escape special characters.
Second: *nix systems are case sensitive, please try mysql instead of MySQL
Update
You could also try to type your password into a file and read it with your script
mysql -u root -p`cat /tmp/pass` -e "SHOW DATABASES"
The file /tmp/pass should contain your password without any newline char at the end.
Update 2
Your Script is wrong.
You can either use mysql ... -e SELECT * FROM TABLE or mysql ... << EOF (without -e). You should not mix them.
Don't forget to pass the databasename as a parameter (or with use databasename;) in the sql
Don't forget to add a ; after every sql command, if you have multiple statements
Method One:
mysql -u root -ppassword databasename -e "SELECT * FROM main"
Method Two:
mysql -u root -ppassword databasename << EOF
SELECT * FROM main
EOF
Method Three:
mysql -u root -ppassword << EOF
USE databasename;
SELECT * FROM main;
EOF
mysql --user=root --password=xxxxxx -e "source dbscript.sql"
This should work for Windows and Linux.
If the password content contains a ! (Exclamation mark) you should add a \ (backslash) in front of it.

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'";