SSHによるsh -cの変数拡張の実行

SSHによるsh -cの変数拡張の実行

LXCコンテナでSSHを介してsh -cを介してコマンドを実行しようとしています。 lxc-attachが含まれているので、sh -c次のように使用する必要がありますssh <host> "lxc-attach -- sh -c \"<command>;<command>\""。これはほとんどの状況に当てはまります。ただし、コマンドでリテラル環境変数を使用しようとすると、変数は引き続き拡張されます。

問題は次のように単純化できます。テキストを印刷したいです。$HOME

ローカル:

user@local:~$ sh -c 'echo $HOME'
/home/user
# Despite single quote the variable gets expanded, one has to escape the $ sign
user@local:~$ sh -c 'echo \$HOME'
$HOME

これまでは大丈夫でしたが、SSHで試してみると離れて:

user@local:~$ ssh remote "sh -c 'echo \$HOME'"
/root
user@local:~$ ssh remote 'sh -c 'echo \$HOME''

user@local:~$ ssh remote "sh -c \'echo \$HOME\'"
/root': 1: Syntax error: Unterminated quoted string

エスケープ変数のいくつかのバリエーションを試しました。引き続き拡張、何も印刷されない、またはエラーが発生します。

ベストアンサー1

SSHは常にリモートでシェルを実行して、ユーザーが提供したコマンドラインを処理します。望むより: SSHリモートコマンドラインパラメータを解析する方法

$ ssh remote "sh -c 'echo \$HOME'"
/root

ローカルシェルは引用符階層をキャンセルし、\$SSHになり、リモートシェルに$ 転送して実行し、明示的に拡張を開始します。sh -c 'echo $HOME'sh$HOME

$ ssh remote 'sh -c 'echo \$HOME''

これは以下に関連しています。

$ ssh remote 'sh -c echo' \$HOME              # or
$ ssh remote 'sh -c echo' '$HOME'

空白は引用されていません(echo元にはありませんでしたが関係ありません)。

SSHはスペースで取得したパラメータを連結し、文字列をリモートでsh -c echo $HOME送信します。内部シェルを介して渡される結果コマンド-cはcommandですecho。その内部$HOMEへの拡張。$0sh

$ ssh remote "sh -c \'echo \$HOME\'"
/root': 1: Syntax error: Unterminated quoted string

ここでローカルシェルは再びなり、\$SSH$は文字列を sh -c \'echo $HOME\'リモートで送信します。ここで、SSH実行シェルはこれらのバックスラッシュを解析し、引数、、sh-c拡張)を使用してコマンドを実行します。これ'echo/home/username'$HOME内部に shコマンドに'echo終了しない引用符付き文字列があることを確認してください。

君にはこんなことが必要だ

$ ssh localhost 'sh -c "echo \\\$HOME"'
$HOME

sh -cローカルシェル(上記の一重引用符)、SSHによって開始されたシェル(バックスラッシュ)、およびユーザーが起動するシェル(他のレベルのバックスラッシュ、1つはfor、1つはfor)を保護するための\拡張です$

または、1つのバックスラッシュの代わりに単一引用符を使用してください。

$ ssh localhost 'sh -c '\''echo \$HOME'\'
$HOME

ここまたは類似のファイルまたは(参照)文書を介してコマンドを渡す方が簡単です。

$ ssh localhost 'sh -s' <<'EOF'
echo '$HOME'
EOF
$HOME

また見なさい:ssh $host $FOO および ssh $host "sudo su user -c $FOO" タイプ構成で参照されます。

おすすめ記事