一重引用符と、その一重引用符内の他のコマンド、および変数を含むbash スクリプトからコマンドを実行したいと考えています。
例えばrepo forall -c '....$variable'
この形式では、$
はエスケープされ、変数は展開されません。
以下のバリエーションを試しましたが、拒否されました。
repo forall -c '...."$variable" '
repo forall -c " '....$variable' "
" repo forall -c '....$variable' "
repo forall -c "'" ....$variable "'"
変数の代わりに値を代入すると、コマンドは正常に実行されます。
どこが間違っているのか教えてください。
ベストアンサー1
一重引用符内では、例外なくすべてが文字通り保存されます。
つまり、引用符を閉じて何かを挿入し、再度入力する必要があります。
'before'"$variable"'after'
'before'"'"'after'
'before'\''after'
単語の連結は、単純に並置することで行われます。確認できるとおり、上記の各行はシェルにとって単一の単語です。引用符 (状況に応じて一重引用符または二重引用符) は単語を分離しません。引用符は、空白、、などのさまざまな特殊文字の解釈を無効にするためにのみ使用されます。$
引用;
符に関する優れたチュートリアルについては、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
。これは、変数の展開やその他の形式の解釈なしに、文字通りに解釈されることを意味します。