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 passer 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. Sur la page de manuel sudo:
-S, --stdin
Write the prompt to the standard error and read the password from the standard input instead of using the terminal device. The password must be followed by a newline character.
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 transférant 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 étant donné qu’il s’exécute à l’intérieur de ssh, à droite de notre pipe?" Lorsque nous exécutons plusieurs commandes et que nous transmettons le résultat 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. Nous pouvons le voir en action en exécutant l'intégralité de la commande et en mettant en arrière-plan le groupe de processus (Ctrl-z) avant de saisir notre mot de passe, puis en affichant l'arbre de 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 n’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 se peut qu’il apparaisse une fois que vous avez commencé à taper.
Remarque: j'ai simplement ajouté une entrée de fichier hôte pour "remote_Host" sur mon ordinateur local pour la démonstration.