回答:
here-docを書きたいときに、どのドキュメントも展開したり、特殊文字を解釈したくない場合は、次のようにラベルを一重引用符で囲むことができます。
$ cat >file <<'EOF'
echo "$ABC=home_dir"
EOF
ただし、この例で説明されている状況ははるかに複雑です。なぜなら、このコンテンツを実際にssh経由でリモートシステムに送信し、sudoによって実行され、シェルも呼び出しているからです(シェルはコンテンツを展開します)同じように)。これを正しくするには、より多くの引用レベルが必要になりますが、それでもsudoには端末が必要で(パスワードを要求できる)、stdinからリダイレクトされているため、まだ機能しません。使用しても、ssh -t
ここでは役に立ちません。
また、ヨハンにも同意します。これが本当にあなたが望むものであるかは明らかではありません。シェル変数参照に値を割り当てることは違法であることに注意してください。したがって、作成しようとしているこのファイルがシェルスクリプトであると想定される場合、説明したとおりに機能しません。少しバックアップして、本当にやりたいことを説明していただければ、さらにお手伝いできます。
エスケープ $
$ ssh hostname sudo -s <<EOF
echo "\$ABC=home_dir" > file
EOF
私はあなたのユースケースが何であるかを知りませんが、通常あなたはhome_dir=$ABC
代わりに欲しいです$ABC=home_dir
。
=home_dir
し、ファイルに格納される可能性が高い文字列を「ファイル」に格納するシェルスクリプトが生成されるようです。もちろん、ユースケースが何であるかはわかりません
$
がリモートシェルに送信されますが、そのシェルは$ABC
文字列をにエコーする前に展開されfile
ます。リテラル$
をファイルに書き込むには、別の(エスケープされた)バックスラッシュ:が必要echo "\\\$ABC=home_dir"
になるため、リモートシェルはを受け取りecho "\$ABC=home_dir"
ます。
cat
リモートエンドのプロセスに文字列を送信することで、引用のレベルを節約できます。
echo 'echo $ABC=home_dir' | ssh hostname sudo -s "cat > file"
一重引用符$
はローカルエンドを保護します。文字列は、他のシェルコマンドの引数ではなくcat
(経由でsudo
)直接読み取られるため、もう一方のシェルには表示されません。
コードでは、次のものを保護するためにエスケープの追加レイヤーが必要になります$
。
$ ssh hostname sudo -s <<EOF
echo "\\\$ABC=home_dir" > file
EOF
\$
リモートシェルがリテラル$
をファイルに書き込むように、リモートホストにリテラルを送信する必要があります。here-docマーカーを引用することで、これを単純化することもできます。
$ ssh hostname sudo -s <<\EOF
echo "\$ABC=home_dir" > file
EOF