Voici une version modifiée de la réponse de Willie Wheeler qui transfère le(s) fichier(s) via tar mais prend également en charge le passage d'un mot de passe à sudo sur l'hôte distant.
(stty -echo; read passwd; stty echo; echo $passwd; tar -cz foo.*) \
| ssh remote_host "sudo -S bash -c \"tar -C /var/www/ -xz; echo\""
Le petit supplément de magie ici est l'option -S pour sudo. Selon la page de manuel de sudo :
-S, --stdin Écrire l'invite dans la sortie d'erreur standard et lire le mot de passe depuis l'entrée standard au lieu d'utiliser le périphérique terminal. Le mot de passe doit être suivi d'un caractère de nouvelle ligne.
Nous voulons en fait que la sortie de tar soit redirigée vers ssh, ce qui redirige ensuite l'entrée standard de ssh vers la sortie de tar, supprimant ainsi tout moyen de transmettre le mot de passe à sudo depuis le terminal interactif. (Nous pourrions utiliser la fonction ASKPASS de sudo à l'autre bout, mais c'est une autre histoire). Nous pouvons toutefois transmettre le mot de passe à sudo en le capturant à l'avance et en le préfixant à la sortie de tar en effectuant ces opérations dans un sous-shell et en passant la sortie du sous-shell à travers ssh. Cela présente également l'avantage supplémentaire de ne pas laisser une variable d'environnement contenant notre mot de passe traîner dans notre shell interactif.
Vous remarquerez que je n'ai pas exécuté 'read' avec l'option -p pour afficher une invite. C'est parce que l'invite du mot de passe de sudo est commodément renvoyée vers la sortie d'erreur standard de notre shell interactif via ssh. Vous pourriez vous demander "comment sudo est-il exécuté alors qu'il s'exécute à l'intérieur de ssh à droite de notre pipe ?" Lorsque nous exécutons plusieurs commandes et redirigeons la sortie de l'une vers l'autre, le shell parent (le shell interactif dans ce cas) exécute chaque commande dans la séquence immédiatement après avoir exécuté la précédente. À chaque commande derrière un pipe qui est exécutée, le shell parent attache (redirige) la sortie standard du côté gauche vers l'entrée standard du côté droit. La sortie devient alors une entrée au fur et à mesure qu'elle passe par les processus. Nous pouvons voir cela en action en exécutant la commande entière et en mettant le groupe de processus en arrière-plan (Ctrl-z) avant de taper notre mot de passe, puis en regardant l'arbre des processus.
$ (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"`
Notre shell interactif est PID 7168, notre sous-shell est PID 7969 et notre processus ssh est PID 7970.
Le seul inconvénient est que read acceptera l'entrée avant que sudo n'ait le temps de renvoyer son invite. Sur une connexion rapide et un hôte distant rapide, vous ne remarquerez pas cela, mais vous pourriez le remarquer si l'un ou l'autre est lent. Tout retard n'affectera pas la capacité à entrer l'invite ; elle pourrait simplement apparaître après que vous ayez commencé à taper.
Notez simplement que j'ai ajouté une entrée de fichier host pour "remote_Host" sur ma machine locale pour la démo.