二重引用符のエスケープ防止

二重引用符のエスケープ防止

Bashスクリプトからいくつかのコマンドを実行したいと思います。
一重引用符を使用すると、変数は値ではなくリテラルとして扱われます。
たとえば、これは二重引用符をエスケープして、すべてを混乱させることなく引用符と二重引用符の混合を処理する方法とは異なりますls "$SOME_DIR"。たとえば、次のことを確認する方法は次のとおりです。 ls '$SOME_DIR'

ssh server.com "mkdir \"/foo/bar/"$final"\""  

命令が長くなるほど読みにくくなり、破損しやすくなるため、これらのすべての脱出をどのように回避できますか?

答え1

複数回使用した後の最も簡単な解決策は次heredocsherestringsとおりです。

ssh server.com "mkdir '/foo/bar/$final'"

はい、のように一重引用符にもかかわらず、bash変数の置換は引き続き発生します。$finalecho "test'$final'"

$final注:@muruが指摘したように、単一引用符が含まれている場合は機能しません。

答え2

反対参照、(つまり二重引用符内の一重引用符その逆に)、エスケープの代わりに使用できます。エスケープ文字を使用しないここにファイルecho、以下を使用してこのテキストを表示する方法を検討してください。

彼は後ろを振り返らず、「話すこともできない」と話した。

二重引用符または一重引用符で囲んでも機能しません。逆引用符を交互に使用すると機能します。

echo "He didn't look back, and said "'"It can'"'t be helped."'"'

出力:

He didn't look back, and said "It can't be helped."

残念ながら、上記はecho脱出だけでなく読書も困難です。

視覚的な単調さを減らすために、逆引用符を使用し、必要に応じて両方をエスケープすることをお勧めします。

echo "He didn't look back, and said \"It can't be helped.\""

コードに適用:

ssh server.com 'mkdir "'"/foo/bar/$final"\"

$final含まれていても'

見積もりを拡張すると、次のようになります。

  1. 'mkdir "'、スペースと左二重引用符が保持されます。
  2. "/foo/bar/$final"$final開始する前の内容を返しますssh
  3. \"二重引用符を閉じてディレクトリ名を保持します。ssh

答え3

実際の要件は、ローカルにコマンドを送信する前またはリモートでコマンドを送信した後に変数を拡張したい場所/タイミングによって大きく異なります。どちらの場合も有効です。いずれにしても、コマンドが1行に入る場合は、<<<それぞれ二重引用符または一重引用符を使用してコマンドをリダイレクトすることをお勧めします。

1. コマンドを送信する前に変数を解析します。

final="defined_locally"; ssh server.com <<<"final="defined_remotely" ;mkdir /foo/bar/"$final" "

2. コマンドを送信した後、変数を解析します。

final="defined_locally"; ssh server.com <<<'final="defined_remotely"; mkdir /foo/bar/"$final" '

最初の項目が作成されます。

/foo/bar/define_locally

二つ目は作ります。

/foo/bar/define_remotely

リモートサーバーのディレクトリ

ご覧のとおり、1つのコマンドにローカル変数とリモート定義変数を混在させるまで、どちらの場合もエスケープは必要ありません。

修正する:

<<<

厳密に言えば、リダイレクトではありません。ここで文字列

アップデート2:

ご指摘いただいた@Rastapopoulosに感謝します。

Pseudo-terminal will not be allocated because stdin is not a terminal コマンドの実行に伴うメッセージ

ダメージがなくても

答え4

これは組み込みタスクですかprintf

ldo@theon:~> f='He didn'\''t look back, and said "It can'\''t be helped."'
ldo@theon:~> echo "$f"
He didn't look back, and said "It can't be helped."
ldo@theon:~> ssh hypatia echo "$f"
bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file
ldo@theon:~> ssh hypatia echo $(printf %q "$f")
He didn't look back, and said "It can't be helped."

関連情報