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
への拡張。$0
sh
$ 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" タイプ構成で参照されます。