Check if mysql user exists in bash script, getting error - mysql

I am working on a bash script to check if a mysql user exists, with following commands:
checkuser=`mysql -u $mysqlroot -p$rootpw -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$user_name') ;"`
lastchr=${checkuser#${checkuser%?}}
if [ $lastchr == 1 ] ; then
clear
echo "ERROR: mysql user exists"
fi
My problem is, that the terminal always gives me following feedback:
/etc/hosting: line 775: syntax error near unexpected token `('
/etc/hosting: line 775: `checkuser=`mysql -u $mysqlroot -p$rootpw -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$user_name') ;"`'
I tried with escaping the "(" and ")", but I didn't success.
What am I doing wrong? I tried all different kinds of escaping, single quotes, ... and it didn't help.
Kind regards
EDIT:
because maybe needed, previous lines:
echo "creating mysql user ..."
echo ""
read -p "enter username: " user_name
if [[ -z "$user_name" ]] ; then
clear
echo "username mustn't be empty!"
create_mysql_user # calls function again
fi
# check username length
if [ ${#my_user} -gt 16 ] ; then
clear
echo "ERROR: the username mustn't be longer than 16 characters"
create_mysql_user
fi

This is an old question but still searchable on internet. I would like to answer it because it doesn't have a proper answer.
To check the existence of mysql user using bash, you can use the following package jq to transform the query result to readable output as list of users in array format:
# Get list of all sql users
sql_users=$(mysql -e "SELECT USER FROM mysql.user;" | jq -rR .)
check_sql_user=$(echo "${sql_users}" | grep "username_to_check")
if [[ -z "${check_sql_user}" ]]; then
echo "No user found"
# Call create user here
else
echo "User found"
fi

Related

How do not remove leading zero from variable in a Bash MySQL query?

I am trying to query against the database to validate if a registry exists. I created I bash script to make that:
read -p "`echo $'\n '`-------------`echo $'\n '` Insert a CPF: `echo $'\n '`-------------`echo $'\n '`" CPF
USER_IN_OPTOUT=$(mysql -u $BMB_MYSQL_USER -h $BMB_MYSQL_HOST -NB -se "SELECT cpf FROM optout WHERE cpf = $CPF;")
if [[ ${USER_IN_OPTOUT} == *"${CPF:0}"* ]]; then
echo "----------------------------------------"
echo "User already exists."
echo "----------------------------------------"
else
echo "---------------------------------------"
echo "User does not exists."
echo "---------------------------------------"
exit 1
fi
The variable CPF ($CPF) is equal to 00324323721. As this registry exists it returns the cpf, as expected. However, this query is removing leading zeros returning 324323721. I expect that the returns be exactly 00324323721. How can I do that?

Mysql error handling in queries bash script

I need to catch any invalid credentials while connecting to MariaDB, and overwrite the stderr stream explaining the error.
I have tried to use the following since it seemed to be the easiest and shortest code, but the database throws it's own error instead of displaying mine so I do not think the condition is even working.
right after the mysql command
if [ "$?" -eq 0 ]; then
echo "There is something wrong with the arguments provided">&2
exit 2
else
: #some code
fi
TABLES=$(mysql --skip-column-name -u $USER -pPASSWORD $DB -e "SHOW TABLES;" | grep -v '+' | cut -d' ' -f2)
if [ "$?" -eq- 0 ]; then
echo "There is something wrong with the arguments provided">&2
exit 2
else
: #some code
fi
I was expecting to see my stderr message appearing instead it is showing the mariadb error message on the screen.
The exit status of a pipeline is the status of the last command in the pipeline. So in your case, it's the status of cut, not mysql.
You can use the PIPESTATUS array to get the exit status of other commands in the pipeline. However, this is tricky when the pipeline is in a command substitution, because you need PIPESTATUS from the subshell. See Pipe status after command substitution
If you don't want to see the database error message, you need to redirect stderr.
You need to check if the status is not 0. In the shell, 0 means success.
TABLES=$(mysql --skip-column-name -u $USER -pPASSWORD $DB -e "SHOW TABLES;" 2>/dev/null | grep -v '+' | cut -d' ' -f2; echo ": ${PIPESTATUS[0]}")
status=${TABLES##*: }
if [ $status -ne 0 ]
then
echo "There is something wrong with the arguments provided">&2
exit 2
else
# Remove the appended status
TABLES=${TABLES%:*}
TABLES=${TABLES%$'\n'}
fi

How to check if a table exists in a MySQL database using shell script?

i am trying to check whether a table is empty or not using shell script
the code that i have is
#!/bin/bash
if [ "mysql -u user -ppassword -hserver dbname -e 'select count(*) from test_dec;'" != 0 ];
then
echo "table not empty"
else
echo "table empty"
fi
but when i run this it always displays "table not empty" even if the output of the query is 0.
user#server$ ./table_check.sh
table not empty
what is wrong here?
This is my version of the script and it will first check if table exists and if yes will check if the table is empty.
BASH
#!/bin/bash
# Prepare variables
TABLE=$1
SQL_EXISTS=$(printf 'SHOW TABLES LIKE "%s"' "$TABLE")
SQL_IS_EMPTY=$(printf 'SELECT 1 FROM %s LIMIT 1' "$TABLE")
# Credentials
USERNAME=YOUR_USERNAME
PASSWORD=YOUR_PASSWORD
DATABASE=YOUR_DATABASE_NAME
echo "Checking if table <$TABLE> exists ..."
# Check if table exists
if [[ $(mysql -u $USERNAME -p$PASSWORD -e "$SQL_EXISTS" $DATABASE) ]]
then
echo "Table exists ..."
# Check if table has records
if [[ $(mysql -u $USERNAME -p$PASSWORD -e "$SQL_IS_EMPTY" $DATABASE) ]]
then
echo "Table has records ..."
else
echo "Table is empty ..."
fi
else
echo "Table not exists ..."
fi
USAGE
First before using this script you need to replace YOUR_USERNAME, YOUR_PASSWORD and YOUR_DATABASE_NAME with the corresponding values. Then:
# bash SCRIPT_NAME TABLE_TO_CHECK
bash my_script my_table
where SCRIPT_NAME( my_script ) is the name of the file holding the above script content and TABLE_TO_CHECK( my_table ) is the name of the table that you want to check for.
EXPECTED OUTPUT
Checking if table <my_table> exists ...
Table exists ...
Table is empty ...
COUPLE OF WORDS ABOUT THE CODE
Store the first argument from the command line in variable TABLE
TABLE=$1
Prepare two variables that will hold the SQL queries used to check.
Note that printf is used to insert the table name in the variables, because $('SHOW TABLES LIKE "$TABLE"') is not going to work.
SQL_EXISTS=$(printf 'SHOW TABLES LIKE "%s"' "$TABLE")
SQL_IS_EMPTY=$(printf 'SELECT COUNT(*) as records FROM %s' "$TABLE")
Check if table exists. SHOW TABLES LIKE "table_name" will return empty string if the table does not exist and the if statement will fail. Usage of the $ like $(echo 1 + 2) means - evaluate whatever is inside the parentheses and return that as a value.
if [[ $(mysql -u $USERNAME -p$PASSWORD -e "$SQL_EXISTS" $DATABASE) ]]
Finally we check if table is empty. Using the previous approach. Basically we check if MySQL will return empty string (for empty tables), otherwise the query will return some text as a result and we can consider the table not empty.
if [[ $(mysql -u $USERNAME -p$PASSWORD -e "$SQL_IS_EMPTY" $DATABASE) ]]
This should work
if [ $(mysql -u root -p -e \
"select count(*) from information_schema.tables where \
table_schema='db_name' and table_name='table_name';") -eq 1 ]; then
echo "table exist"
exit 1
else
echo "table doesn't exist"
exit 1
fi
I think below will do your work,
#!/bin/bash
if [ $(mysql -u user -ppassword -hserver dbname -sse "select count(*) from test_dec;") -gt 0 ];
then
echo "table not empty"
else
echo "table empty"
fi
3 changes from your script,
enclose whole mysql statement part inside $(..) --> to make LHS the result of what goes inside $(...)
change -e to -sse in mysql connection statement --> to get only result of query to output without header and table structure.
Change != to -gt --> operator for integer comparison in bash
This works for me when testing if we need to re-import a database.
databasename="mydatabasename";
tablename="tableweneed";
dbhost="localhost";
username="user";
password="password";
dbtest=$(mysql -h ${dbhost} -u ${username} -p${password} -s -N -e "select count(*) as tablecount from information_schema.tables WHERE table_schema='${databasename}' and table_name='${tablename}'")
if [ "$dbtest" == 1 ]; then
echo "Database is ok"
else
echo "Database is being re-imported"
mysql -h ${dbhost} -u ${user} -p${password} ${databasename} < /somefolderonmysystem/importdb.sql
fi
After trying a few different methods, this is what we used:
if [[ $(mysql --execute "SHOW TABLES FROM ${DB_NAME} LIKE '${DB_PREFIX}options';") -gt 0 ]]; then
...and yes, we define mysql as a function earlier in the script, and the database name and database prefix are also defined in a configuration file (this is part of our SlickStack project).
function mysql {
command mysql --user=root --host=localhost --protocol=socket --port=3306 --force "$#"
}
You can change the name of this function in your bash script as desired.
Example: https://github.com/littlebizzy/slickstack/blob/master/bash/ss-install-wordpress-config.txt

UNIX SHELL SCRIPT - MYSQL issue

Below Unix shell script fails saying unexpected end of file at the mysql line before $selectg line. Not sure what mistake i am doing. Provided part of script below. Could anyone help me out.
#!/bin/bash
ip="77.299.113.81"
pass="-ptest123"
read -d '' selectg <<EOGG SELECT * FROM agstatus ; EOGG
for row in `mysql -h $ip -u root $pass "ruttt" -e "SELECT databasename FROM master.customers"`; do
rownum=$((rownum+1))
echo "Row:$row"
if [ $rownum -ne 1 ]; then
mysql -u tsadm -p'test123' -h 77.299.113.81 Csfgat << eof
$selectg
eof
fi
done
echo "done"
The end token of a here document has to be on a line by itself:
read -d '' selectg <<EOGG
SELECT * FROM agstatus;
EOGG
Alternatively, you can use a here string:
read -d '' selectg <<< "SELECT * FROM agstatus;"
Or in your specific case, a plain ol' assignment:
selectg="SELECT * FROM agstatus;"

Shell script if condition

I'm writing a script which runs the following command
mysql -u root -e "show databases"
and this will display a list of databases.
If this table doesn't contain a database by name "userdb", it should do the following-
if [ ... ]; then
echo "error"
exit
fi
What do i write in the if [ ... ] condition?
You can check with grep if the table name is listed. grep -q will not print anything to the console but will set the exit status according to the result (the exit status will then be checked by if).
if ! mysql -u root -e 'show databases' | grep -q '^userdb$' ; then
echo error
exit
fi
About the regular expression: '^' matches the beginning of the line and '$' matches the end of the line (to avoid a false positive for database names containing userdb, e.g. userdb2)
Try this one:
usedb=DBname
check=`mysql -u root -e "show databases" | grep $userdb`
if [ "$check" != "$userdb" ]; then
echo "error"
exit
fi
But here will be an error if line with database name contain any other information.
Try to workaround it with regexp