How to execute a bash command stored as a string with quotes and asterisk
BashScriptingEscapingQuotesBash 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"'