web-dev-qa-db-ja.com

ヒアドキュメントでの変数の受け渡しと設定

さまざまなリモートマシンでさまざまなことを実行する必要があるスクリプトがあります。ヒアドキュメントはこれでうまくいくと思いましたが、スクリプトの他の場所で定義された変数を使用することはできませんandヒアドキュメントで定義されたもの。

ここにいくつかのコードがあります:

#!/bin/sh

FOO="foo"
ssh some.remote.Host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=$BAR"
EOF

これは、次のものだけを出力します。

FOO =

BAR = bar

ただし、EOFの行を次のように引用すると:ssh some.remote.Host << "EOF"の場合、次の情報のみが出力されます。

FOO = foo

BAR =

ヒアドキュメント内でboth変数を使用する方法についてのヒントはありますか?

ありがとう。

24
trubliphone

要するに、使用:

  • 引用されていないheredocキーワード、例:EOF
  • outer(つまりlocal)変数の通常のドル記号、例:$FOO
  • エスケープドル記号inner(つまりremote)変数、たとえば\$BAR

Heredocキーワード(つまりEOF)を引用符で囲まないでおくと、heredoc本体がローカルで処理されるため、$FOOfooに、BARは空の文字列。次に、sshコマンドは次のようになります。

BAR="bar"
echo "FOO=foo"
echo "BAR="

Heredocキーワードを引用すると、変数の展開が抑制されるため、sshコマンドは次のようになります。

BAR="bar"
echo "FOO=$FOO"
echo "BAR=$BAR"

FOOはリモートシェル環境ではおそらく定義されていないため、式"FOO=$FOO""FOO=''"として評価されます。つまり、FOOは空の文字列に設定されます。

両方の変数を使用する場合は、heredocキーワードを引用符で囲まないでおく必要があります。これにより、ローカルで定義された変数に対して変数の展開が行われ、リモートで展開する変数を(バックスラッシュで)エスケープします。 :

#!/bin/sh

FOO="foo"
ssh some.remote.Host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=\$BAR"
EOF

この場合、sshコマンド(リモートサーバーが受信したもの)は次のようになります。

  BAR="bar"
  echo "FOO=foo"
  echo "BAR=$BAR"
34
igal