1. ホーム
  2. bash

[解決済み] Bashでコマンド内のシングルクォート内の変数を展開する

2022-03-17 18:55:18

質問

からのコマンドを実行したいのですが バッシュスクリプト は、シングルクォートと、シングルクォートの中にあるいくつかの他のコマンドと、変数を持っています。

repo forall -c '....$variable'

この形式では $ はエスケープされ、変数は展開されません。

以下のバリエーションを試しましたが、拒否されました。

repo forall -c '...."$variable" '

repo forall -c " '....$variable' "

" repo forall -c '....$variable' "

repo forall -c "'" ....$variable "'"

変数の代わりに値を代入すると、コマンドは正常に実行されます。

どこが間違っているのか教えてください。

解決方法は?

一重引用符の中では、すべてが例外なく文字通りに保存されます。

つまり、引用符を閉じてから何かを挿入し、もう一度入力し直さなければならないのです。

'before'"$variable"'after'
'before'"'"'after'
'before'\''after'

単語の連結は単純に並列化で行われます。確認できるように、上の行はそれぞれシェルにとっては1つの単語です。引用符(状況に応じて一重引用符や二重引用符)は単語を分離するものではありません。それらは、空白文字のような様々な特殊文字の解釈を無効にするためにのみ使用されます。 $ , ; ... 引用の良いチュートリアルは、Mark Reedの回答を参照してください。また、関連する bashでエスケープする必要がある文字は?

シェルが解釈する文字列を連結してはいけない

変数を連結してシェルコマンドを構築することは絶対に避けるべきです。これはSQLの断片を連結するのと同じような悪い考えです(SQLインジェクション!)。

通常、コマンドにプレースホルダーを持たせ、呼び出し側が呼び出し引数リストから受け取ることができるように、コマンドを変数と一緒に提供することが可能です。

例えば、次のようなものは非常に安全ではありません。これをやってはいけません

script="echo \"Argument 1 is: $myvar\""
/bin/sh -c "$script"

の内容が $myvar が信頼できない場合、以下のような悪用が可能です。

myvar='foo"; echo "you were hacked'

上記の呼び出しの代わりに、位置引数を使用します。以下の呼び出しの方が良い -- 悪用されない。

script='echo "arg 1 is: $1"'
/bin/sh -c "$script" -- "$myvar"

への代入では、シングルテックを使用していることに注意してください。 script これは、変数の展開や他の形式の解釈をせずに、文字通りに解釈することを意味します。