web-dev-qa-db-ja.com

引用符とアスタリスクを含む文字列として格納されたbashコマンドを実行する方法

次のコマンドを実行してみます。

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

それを文字列に格納します。

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

試して :

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

実行してみてください。

$cmd

そして、私は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]
(...)

私は引用符で明らかに悪いことをしているのですが、何が問題なのか分かりません。

219
Barth

やってみました:

eval $cmd

*をエスケープする方法についての次の質問は、裸の場合や二重引用符で囲まれた文字列では特別な意味があるためです。一重引用符を使用してください。

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

ボーナス:それはまたいい読みます:eval mysql query ;-)

315
slebetman

BashFAQ#5 で説明されているように、文字列ではなく配列を使用してください。

文字列を使用するのは非常に悪いセキュリティプラクティスpassword(またはクエリ内のwhere句、その他のコンポーネント)がユーザー指定の場合を考えてください。 ;あなたはeval$(rm -rf .)を含むパスワードを与えたくありません。


ローカルコマンドを実行するだけ

cmd=( mysql AMORE -u username -ppassword -h localhost -e "SELECT  Host  FROM amoreconfig" )
"${cmd[@]}"

明確にコマンドを印刷する

cmd=( mysql AMORE -u username -ppassword -h localhost -e "SELECT  Host  FROM amoreconfig" )
printf 'Proposing to run: '
printf '%q ' "${cmd[@]}"
printf '\n'

SSH経由でコマンドを実行する(方法1: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"

SSH経由でコマンドを実行する(方法2:コマンドライン)

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"
41
Charles Duffy

これを試して

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

あなたも "eval"は必要ありません。文字列の前にドル記号を入れるだけです。

cmd="ls"
$cmd
2
David Beckwith