これは、ファイルをtar経由で転送するが、リモートホスト上のsudoへのパスワードの受け渡しもサポートするWillie Wheelerの回答の修正版です。
(stty -echo; read passwd; stty echo; echo $passwd; tar -cz foo.*) \
| ssh remote_host "sudo -S bash -c \"tar -C /var/www/ -xz; echo\""
ここでのちょっとした魔法は、sudoの-Sオプションです。sudoのmanページから:
-S、--stdinプロンプトを標準エラーに書き込み、端末デバイスを使用する代わりに標準入力からパスワードを読み取ります。パスワードの後に改行文字を続ける必要があります。
ここで、実際にtarの出力をsshにパイプし、sshのstdinをtarのstdoutにリダイレクトし、対話式端末からsudoにパスワードを渡す方法を削除します。(リモートエンドでsudoのASKPASS機能を使用できますが、それは別の話です。)パスワードを事前にキャプチャし、サブシェルでこれらの操作を実行してtar出力に追加することで、sudoにパスワードを取得できますサブシェルをsshに。これには、パスワードが含まれる環境変数を対話型シェルに残さないという利点もあります。
プロンプトを表示するために-pオプションを指定して 'read'を実行しなかったことにお気づきでしょう。これは、sudoからのパスワードプロンプトが、sshを介してインタラクティブシェルのstderrに便利に戻されるためです。「パイプの右側のssh内でsudoが実行されている場合、sudoはどのように実行されますか?」複数のコマンドを実行し、1つの出力を別のコマンドにパイプすると、親シェル(この場合は対話型シェル)は、前のコマンドを実行した直後にシーケンス内の各コマンドを実行します。パイプの背後にある各コマンドが実行されると、親シェルは左側の標準出力を右側の標準入力にアタッチ(リダイレクト)します。出力は、プロセスを通過するときに入力になります。
$ (stty -echo; read passwd; stty echo; echo $passwd; tar -cz foo.*) | ssh
remote_host "sudo -S bash -c \"tar -C /var/www/ -xz; echo\""
[sudo] password for bruce:
[1]+ Stopped ( stty -echo; read passwd; stty echo; echo
$passwd; tar -cz foo.* ) | ssh remote_host "sudo -S bash -c \"tar -C
/var/www/ -xz; echo\""
$ pstree -lap $$
bash,7168
├─bash,7969
├─pstree,7972 -lap 7168
└─ssh,7970 remote_host sudo -S bash -c "tar -C /var/www/ -xz; echo"`
インタラクティブシェルはPID 7168、サブシェルはPID 7969、sshプロセスはPID 7970です。
唯一の欠点は、sudoがプロンプトを送り返す前にreadが入力を受け入れることです。高速接続と高速リモートホストでは、これに気付くことはありませんが、どちらかが遅い場合は気付くかもしれません。遅延しても、プロンプトを入力する機能には影響しません。入力を開始した後に表示される場合があります。
注:デモ用にローカルマシンに「remote_Host」のホストファイルエントリを追加しただけです。