Вот модифицированная версия ответа Вилли Уилера, которая передает файлы через tar, но также поддерживает передачу пароля в sudo на удаленном хосте.
(stty -echo; read passwd; stty echo; echo $passwd; tar -cz foo.*) \ | ssh remote_host "sudo -S bash -c \"tar -C /var/www/ -xz; echo\""
Немного дополнительной магии здесь - это опция -S для sudo. Со страницы руководства sudo:
-S, --stdin Запишите запрос на стандартную ошибку и считайте пароль со стандартного ввода вместо использования терминального устройства. За паролем должен следовать символ новой строки.
Теперь мы на самом деле хотим, чтобы вывод tar передавался по каналу в ssh, и это перенаправляет stdin ssh на stdout tar, удаляя любой способ передачи пароля в sudo из интерактивного терминала. (Мы могли бы использовать функцию ASKPASS sudo на удаленном конце, но это уже другая история.) Однако мы можем получить пароль в sudo, записав его заранее и добавив к выводу tar, выполнив эти операции в подоболочке и передав вывод подоболочки в ssh. Это также имеет дополнительное преимущество, заключающееся в том, что переменная среды, содержащая наш пароль, не остается зависшей в нашей интерактивной оболочке.
Вы заметите, что я не выполнил "чтение" с параметром -p для печати приглашения. Это связано с тем, что запрос пароля из sudo удобно передается обратно в stderr нашей интерактивной оболочки через ssh. Вы можете задаться вопросом: "Как выполняется sudo, если он запущен внутри ssh справа от нашего канала?" Когда мы выполняем несколько команд и передаем выходные данные одной в другую, родительская оболочка (в данном случае интерактивная оболочка) выполняет каждую команду в последовательности сразу после выполнения предыдущей. По мере выполнения каждой команды за каналом родительская оболочка присоединяет (перенаправляет) stdout левой части к stdin правой части. Затем выходные данные становятся входными по мере прохождения через процессы. Мы можем увидеть это в действии, выполнив всю команду и создав фоновую группу процессов (Ctrl-z) перед вводом нашего пароля, а затем просмотрев дерево процессов.
$ (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.
Единственным недостатком является то, что read примет ввод до того, как sudo успеет отправить обратно запрос. При быстром соединении и быстром удаленном хосте вы этого не заметите, но можете заметить, если и то, и другое работает медленно. Любая задержка не повлияет на возможность ввода приглашения; оно просто может появиться после того, как вы начнете вводить текст.
Примечание: Я просто добавил запись файла хоста для "remote_Host" на свой локальный компьютер для демонстрации.