40

I'm trying to make a bash script that creates a mysql user and database but I can't find a way to feed the sql into mysql, I'm trying with this format:

mysql < echo "query"

But that is not working, see the example below:

mysql --host=localhost --user=user --password=password < echo "CREATE USER 'testuser'@'localhost' IDENTIFIED BY  'jakdJxct8W';
CREATE DATABASE IF NOT EXISTS 'testuser_dev' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON  'testuser_dev' . * TO  'testuser'@'localhost';
CREATE DATABASE IF NOT EXISTS 'testuser_qa' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON  'testuser_qa' . * TO  'testuser'@'localhost';"

How to feed mysql with the queries?

1
  • 1
    not related to the question, but you can also save a lot of typing by setting up your host, user and password in a .my.cnf file Commented May 27, 2011 at 10:09

7 Answers 7

58

Try like this:

echo "select 1" | mysql
Sign up to request clarification or add additional context in comments.

Comments

30

Try using a here document like this:

mysql --host=localhost --user=user --password=password << END

CREATE USER 'testuser'@'localhost' IDENTIFIED BY  'jakdJxct8W';
CREATE DATABASE IF NOT EXISTS 'testuser_dev' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON  'testuser_dev' . * TO  'testuser'@'localhost';
CREATE DATABASE IF NOT EXISTS 'testuser_qa' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON  'testuser_qa' . * TO  'testuser'@'localhost';

END

Alternatively place all you commands in text file and run it:

mysql --host=localhost --user=user --password=password < commands.sql

1 Comment

+1 I'd also like to mention that if the query uses backticks, you need to quote the opening label: mysql <<'END'
26
mysql --batch --silent -e 'SHOW TABLES';

Batch and silent are handy if you are planning to pipe the output

1 Comment

@cerd --batch without --silent shows column headers
12

The reason your attempt did not work was because the < expects a file name and you fed it a string. You would have to do something like

echo "YOURQUERYSTRINGHERE">tmpfile
mysql --host=localhost --user=user --password=password dbname <tmpfile

ken's suggestion of

 mysql  --host=localhost --user=user --password=password -e "QUERY" dbname

can work, but if you try to use bash variables in your query you can fall foul of parameter expansion. eg

QUERY="select * from $MYTABLE WHERE name=\"[email protected]\";"
mysql --host=localhost --user=user --password=password -e "$QUERY" mydbname

may not do what you expect. One option is use

echo "$QUERY"|mysql --host=localhost --user=user --password=password mydbname

which works if the query string contains appropriate quoting. Another option is the "here" document as suggested by dogbane.

1 Comment

Good explanation of OP's error. Thanks for gathering others' responses and explaining caveats!
8

Have you tried mysql -e query?

Comments

1
cat <<EOD | mysql [-u user] [-ppassword] [database]
  select 1;
  select 2;
  select 3;
EOD

in your case

cat <<EOD | mysql -u root -p
    CREATE DATABASE IF NOT EXISTS testuser_dev DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
    GRANT ALL PRIVILEGES ON  testuser_dev.* TO  "testuser"@"localhost";
    CREATE DATABASE IF NOT EXISTS testuser_qa DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
    GRANT ALL PRIVILEGES ON  testuser_qa.* TO  "testuser"@"localhost";
    FLUSH PRIVILEGES;
EOD

Comments

0

For big queries in a bash script, you can try:

read -d '' SQL_QUERY_1 << EOF

SELECT prod.id as id, prod.title as title, comp.name as company, pho.id as photo_id, pho.image as photo_name
FROM products as prod
JOIN accounts as comp
ON comp.id = prod.account_id
JOIN photos as pho
ON pho.id = prod.featured_photo_id;

EOF

echo ${SQL_QUERY_1} | mysql

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.