Voici une version modifiée de la réponse de Willie Wheeler qui transfère le (s) fichier (s) via tar, mais permet également de transmettre 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 plus de magie ici est l’option -S de sudo. De la page de manuel sudo:
-S, --stdin Ecrit l'invite sur l'erreur standard et lit le mot de passe à partir de l'entrée standard au lieu d'utiliser le terminal. Le mot de passe doit être suivi d'un caractère de nouvelle ligne.
Nous voulons maintenant que la sortie de tar soit acheminée vers ssh, ce qui redirige le stdin de ssh vers la sortie standard de tar, supprimant ainsi tout moyen de transmettre le mot de passe à sudo à partir du terminal interactif. (Nous pourrions utiliser la fonction ASKPASS de sudo sur le côté distant, mais ceci est une autre histoire.) Nous pouvons obtenir le mot de passe dans sudo en le capturant à l'avance et en l'ajoutant à la sortie du fichier tar en effectuant ces opérations dans un sous-shell et en redirigeant la sortie du fichier. le sous-shell dans SSH. Cela présente également l’avantage supplémentaire de ne pas laisser une variable d’environnement contenant notre mot de passe suspendu dans notre shell interactif.
Vous remarquerez que je n'ai pas exécuté 'read' avec l'option -p pour imprimer une invite. En effet, l'invite de mot de passe de sudo est renvoyée de manière pratique à stderr de notre shell interactif via ssh. Vous vous demandez peut-être "comment sudo s’exécute-t-il dans la mesure où il s’exécute dans ssh, à droite de notre pipe?" Lorsque nous exécutons plusieurs commandes et que nous transmettons la sortie de l'une à l'autre, le shell parent (le shell interactif dans ce cas) exécute chaque commande dans la séquence immédiatement après l'exécution de la précédente. Au fur et à mesure que chaque commande située derrière un tube est exécutée, le shell parent attache (redirige) la sortie standard du côté gauche au standard stdin. La sortie devient alors une entrée à mesure qu'elle passe par 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 le PID 7168, notre sous-shell est le PID 7969 et notre processus SSH est le PID 7970.
Le seul inconvénient est que read acceptera les entrées avant que sudo ait le temps de renvoyer son invite. Sur une connexion rapide et un hôte distant rapide, vous ne le remarquerez pas, mais vous pourriez le faire si l'un ou l'autre est lent. Tout retard n'affectera pas la possibilité d'entrer l'invite; il pourrait juste apparaître après que vous ayez commencé à taper.
Remarque J'ai simplement ajouté une entrée de fichier hôte pour "remote_Host" à ma machine locale pour la démo.