How to execute a bash command stored as a string with quotes and asterisk

BashScriptingEscapingQuotes

Bash Problem Overview


I try to execute the following command :

mysql AMORE -u username -ppassword -h localhost -e "SELECT  host  FROM amoreconfig"

I store it in a string :

cmd="mysql AMORE -u username -ppassword -h localhost -e\"SELECT  host  FROM amoreconfig\""

Test it :

echo $cmd
mysql AMORE -u username -ppassword -h localhost -e"SELECT host FROM amoreconfig"

Try to execute by doing :

$cmd

And I get the help page of mysql :

mysql  Ver 14.14 Distrib 5.1.31, for pc-linux-gnu (i686) using readline 5.1
Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license
Usage: mysql [OPTIONS] [database]
(...)

I guess I am doing something plain wrong with the quotes but can't find out what is the problem.

Bash Solutions


Solution 1 - Bash

Have you tried:

eval $cmd

For the follow-on question of how to escape * since it has special meaning when it's naked or in double quoted strings: use single quotes.

MYSQL='mysql AMORE -u username -ppassword -h localhost -e'
QUERY="SELECT "'*'" FROM amoreconfig" ;# <-- "double"'single'"double"
eval $MYSQL "'$QUERY'"

Bonus: It also reads nice: eval mysql query ;-)

Solution 2 - Bash

Use an array, not a string, as given as guidance in http://mywiki.wooledge.org/BashFAQ/050">BashFAQ #50.

Using a string is extremely bad security practice: Consider the case where password (or a where clause in the query, or any other component) is user-provided; you don't want to eval a password containing $(rm -rf .)!


Just Running A Local Command
cmd=( mysql AMORE -u username -ppassword -h localhost -e "SELECT  host  FROM amoreconfig" )
"${cmd[@]}"
Printing Your Command Unambiguously
cmd=( mysql AMORE -u username -ppassword -h localhost -e "SELECT  host  FROM amoreconfig" )
printf 'Proposing to run: '
printf '%q ' "${cmd[@]}"
printf '\n'
Running Your Command Over SSH (Method 1: Using Stdin)
cmd=( mysql AMORE -u username -ppassword -h localhost -e "SELECT  host  FROM amoreconfig" )
printf -v cmd_str '%q ' "${cmd[@]}"
ssh other_host 'bash -s' <<<"$cmd_str"
Running Your Command Over SSH (Method 2: Command Line)
cmd=( mysql AMORE -u username -ppassword -h localhost -e "SELECT  host  FROM amoreconfig" )
printf -v cmd_str '%q ' "${cmd[@]}"
ssh other_host "bash -c $cmd_str"

Solution 3 - Bash

try this

$ cmd='mysql AMORE -u root --password="password" -h localhost -e "select host from amoreconfig"'
$ eval $cmd

Solution 4 - Bash

You don't need the "eval" even. Just put a dollar sign in front of the string:

cmd="ls"
$cmd

Solution 5 - Bash

To eliminate the need for the cmd variable, you can do this:

eval 'mysql AMORE -u root --password="password" -h localhost -e "select host from amoreconfig"'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBarthView Question on Stackoverflow
Solution 1 - BashslebetmanView Answer on Stackoverflow
Solution 2 - BashCharles DuffyView Answer on Stackoverflow
Solution 3 - Bashghostdog74View Answer on Stackoverflow
Solution 4 - BashDavid BeckwithView Answer on Stackoverflow
Solution 5 - BashPaul HavensView Answer on Stackoverflow