レイヤ2 SSHを供給するHeredocのsu-cにおけるquoteコマンドのバックティック評価問題

レイヤ2 SSHを供給するHeredocのsu-cにおけるquoteコマンドのバックティック評価問題

次の間接チェーンがあります。

ssh -t root@host1 ssh host2 << EOF\nsu - user2 -c 'kill `cat ~/file_with_pid`'\nEOF

結局のところ、必要なのはホスト2のプロセスをuser2で終了することです(ファイルからpidを読む)。一重引用符の間の部分を除いて、多くの変更はできません。

'kill `cat ~/file_with_pid`'

したがって、私は単に

ssh user2@host2 'kill `cat ~/file_with_pid`'

私の問題は、~ファイルパスのホームが間違ったホームに拡張されることです。これは、バックティックが評価されたときに関連している可能性があります(長いコマンドチェーンのためにこれがいつ発生するのかわかりません)。

必要なものを得るために一重引用符で囲まれた部分をどのように変更しますか?

host2(注:ユーザーとしてどこでもこれを行うことができるので、家をハードコードできないので、「家」が毎回決定されることを願っています。user2user2

答え1

-J@pLumoが提案したように、sshの( "JumpHost")オプションを使用していくつかの参照地獄から抜け出すことができます。

ssh -J root@host1 root@host2 "su user2 -c 'kill \"\$(cat ~/file_with_pid)\"'"

またはここにあるマニュアルを使用してください。

ssh -J root@host1 -T root@host2 <<'EOT'
su user2 -c 'kill "$(cat ~/file_with_pid)"'
EOT

<<'EOT';代わりに、閉じるタグを使用すると、このドキュメント<<EOTでは変数、バックティックなどは拡張されません。

通常、これは-Tsshがpseudo-ttyを割り当てることを防ぎます。この場合、ssh が pseudo-tty を割り当てなかったという警告を防ぎます。何らかの理由で擬似端末が本当に必要な場合は、2つの-tオプションを使用してsshに1つを割り当てることを強制します。地元のstdinはttyではありません。exitここに文書に1つを追加してください。

ssh -J root@host1 -tt root@host2 <<'EOT'
su user2 -c 'kill "$(cat ~/file_with_pid)"'
exit
EOT

ジャンプホストから22番以外のポートに接続する必要がある場合は、次の形式を使用する必要があり-J user@host1:portます-phost2

ssh -J root@host1:port1 -p port2 root@host2 "su user2 -c 'kill \"\$(cat ~/file_with_pid)\"'"

ジャンプホストに別のIDを使用できるショートカットオプションがあるかどうかわかりません(例-i:)。これには設定ファイルを使用する必要があるようです。


あなたの例でEOF\nsu引用されていないのはただEOFnsu、notですEOF<newline>su(それでも動作しません)。

ただし、標準入力をリダイレクトするとssh<<ここで説明するように)、2番目のホストで対話型認証が防止されるため、それでも変更できません。

関連情報