54

I need a variable to hold results retrieved from the database. So far this is basically what I'm trying with no success.

myvariable=$(mysql database -u $user -p $password | SELECT A, B, C FROM table_a)

My understanding of bash commands is not very good as you can see.

1
  • are you storing $user and $password values in seperate line? Commented Jan 7, 2022 at 21:52

11 Answers 11

93

A more direct way would be:

myvar=$(mysql mydatabase -u $user -p$password -se "SELECT a, b, c FROM table_a")
Sign up to request clarification or add additional context in comments.

5 Comments

I was searching the s param, though you need to supply it twice to suppress the column names to be printed
This shoud be the best answer, it does not return column name!
I think the white space between -p and the password must be removed.
As frb said, you need remove the whitespace between -p and password.
This works for me: myvar=$(mysql mydatabase -h <host> -u $user -p$password -se "SELECT a, b, c FROM table_a;") => I added 2 elements: 1) host address and 2) semicolon into SELECT query.
58

I don't know much about the MySQL command line interface, but assuming you only need help with the bashing, you should try to either swap the commands around like so:

myvariable=$(echo "SELECT A, B, C FROM table_a" | mysql database -u $user -p$password)

which echos the string into MySQL. Or, you can be more fancy and use some new bash-features (the here string)

myvariable=$(mysql database -u $user -p$password<<<"SELECT A, B, C FROM table_a")

resulting in the same thing (assuming you're using a recent enough bash version), without involving echo.

Please note that the -p$password is not a typo, but is the way MySQL expects passwords to be entered through the command line (with no space between the option and value).

Note that myvariable will contain everything that MySQL outputs on standard out (usually everything but error messages), including any and all column headers, ASCII-art frames and so on, which may or may not be what you want.

EDIT:
As has been noted, there appears to be a -e parameter to MySQL, I'd go for that one, definitely.

6 Comments

Thanks, the mysql command also did not like the -p.. I needed to use --password=$password.
You can also add a configuration file (called .my.cnf) to your home folder which would plug in your options automatically. That would save some confusion in your script
+1 of .my.cnf -especially to get passwords out of scripts. The -N option is useful to trim field names.
the -s option in the more voted answer remove the column name and give the value only
Trivia: about -p$password option. The POSIX standard allows, although discourage, optional option-attributes. Unlike mandatory option-attributes, which are shown separated from their options by <blank> characters (like in -u $user), optional option-arguments are included within the same argument string as the option (i.e., no spaces). If you find this syntax confusing (I do) you can use the GNU long argument syntax: --password=$password. Anyway, I also advise using a my.cnf file as it has been suggested.
|
20

You have the pipe the other way around and you need to echo the query, like this:

myvariable=$(echo "SELECT A, B, C FROM table_a" | mysql db -u $user -p $password)

Another alternative is to use only the mysql client, like this

myvariable=$(mysql db -u $user -p $password -se "SELECT A, B, C FROM table_a")

(-s is required to avoid the ASCII-art)

Now, BASH isn't the most appropriate language to handle this type of scenarios, especially handling strings and splitting SQL results and the like. You have to work a lot to get things that would be very, very simple in Perl, Python or PHP.

For example, how will you get each of A, B and C on their own variable? It's certainly doable, but if you do not understand pipes and echo (very basic shell stuff), it will not be an easy task for you to do, so if at all possible I'd use a better suited language.

Comments

18

To read the data line-by-line into a Bash array you can do this:

while read -a row
do
    echo "..${row[0]}..${row[1]}..${row[2]}.."
done < <(echo "SELECT A, B, C FROM table_a" | mysql database -u $user -p $password)

Or into individual variables:

while read a b c
do
    echo "..${a}..${b}..${c}.."
done < <(echo "SELECT A, B, C FROM table_a" | mysql database -u $user -p $password)

3 Comments

syntax error near unexpected token <' cut.sh: line 26: done < <
@thevoipman: It's likely your script isn't using Bash. What does your shebang say? Also, since I can't see your script, I can't see where the error might be.
@thevoipman The process substitution seems to be your issue (yes, I know, a year ago, just if anyone comes looking), but it might be possible to do the reverse using a pipeline instead in whatever shell you're using, i.e. echo ... | mysql ... | while read -a row; do ...; done. Keep in mind the while body is in a subshell and will not affect the shell around it.
10

If you want to use a single value in bash use:

  companyid=$(mysql --user=$Username --password=$Password --database=$Database -s --execute="select CompanyID from mytable limit 1;"|cut -f1)

  echo "$companyid"

1 Comment

mysql accepts --skip-column-names (-N) rather than | cut -f1
5

Other way:

Your Script:

#!/bin/sh

# Set these variables
MyUSER="root"   # DB_USERNAME
MyPASS="yourPass"   # DB_PASSWORD
MyHOST="yourHost"    # DB_HOSTNAME
DB_NAME="dbName"
CONTAINER="containerName" #if use docker

# Get data
data=$($MyHOST -u $MyUSER -p$MyPASS $DB_NAME -h $CONTAINER -e "SELECT data1,data2 from table_name LIMIT 1;"  -B --skip-column-names)

# Set data
data1=$(echo $data | awk '{print $1}')
data2=$(echo $data | awk '{print $2}')

# Print data
echo $data1 $data2

2 Comments

-N can be used for --skip-column-names
This answer is most useful!
3
myvariable=$(mysql database -u $user -p$password | SELECT A, B, C FROM table_a)

without the blank space after -p. Its trivial, but without don't work.

1 Comment

If a password contains special characters you may need to add quotes: -p"YOURCOMPLEXPASSWORD"
2

If you have particular database name and a host on which you want the query to be executed then follow below query:

outputofquery=$(mysql -u"$dbusername" -p"$dbpassword" -h"$dbhostname" -e "SELECT A, B, C FROM table_a;" $dbname)

So to run the mysql queries you need to install mysql client on linux

Comments

0
myvariable=$(mysql -u user -p'password' -s -N <<QUERY_INPUT
    use databaseName;
    SELECT fieldName FROM tablename WHERE filedName='fieldValue';
QUERY_INPUT
)
echo "myvariable=$myvariable"

1 Comment

When providing code that solves the problem, it is best to also give at least a short explanation of how it works so that folks reading won't have to mentally parse it line by line to understand the differences.
0

Another example when the table name or database contains unsupported characters such as a space, or '-'

db='data-base'

db_d=''
db_d+='`'
db_d+=$db
db_d+='`'

myvariable=`mysql --user=$user --password=$password -e "SELECT A, B, C FROM $db_d.table_a;"`

Comments

0

My two cents here:

myvariable=$(mysql database -u $user -p$password -sse "SELECT A, B, C FROM table_a" 2>&1 \
   | grep -v "Using a password")

Removes both the column names and the annoying (but necessary) password warning. Thanks @Dominic Bartl and John for this answer.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.