Dans certains rares cas, on peut vouloir exécuter des commandes en tant que root sans avoir la possibilité d'allouer un terminal sur la machine en question.
Pour ceux qui aiment bien lire la fin en premier, je mets la fin au début :-) :
echo "mypassword" |sudo -S id
Pour illustrer le problème, prenons un cas concret qui m'est arrivé.
Un serveur s'est soudainement mis dans un état bizarre, à savoir que tout
marchait, les processus déjà en cours continuaient de s'exécuter, d'autres
processus pouvaient se créer, mais certaines choses ne marchaient pas,
notamment l'allocation de pseudo-terminaux (les /dev/pts/*) ; si je tente
une connexion SSH au serveur, le serveur répond bien, l'authentification se
fait, et au moment d'avoir mon prompt, la connexion se freeze.
Après divers tests, je m'aperçois qu'en passant directement une commande à ssh,
ça marche :
ssh serveur-foireux dmesg
La différence vient du fait que dans le deuxième cas, ssh n'ouvre pas de
pseudo-terminal sur le serveur distant, puisqu'il se contente de récupérer
directement stderr et stdout.
On peut faire en sorte de se connecter sans allouer de terminal sur le serveur
avec l'option -T de la commande ssh :
-T Disable pseudo-tty allocation.
On a ainsi un shell qui s'exécute sur la machine, et on récupère la sortie
brute de stderr et stdout (pas de prompt, d'édition de la commande en cours,
etc…). Pareil pour stdin, ce qui fait que les commandes sudo
ou su
retournent une erreur, étant donné qu'elles font une manipulation spécifique
sur stdin (pas d'echo pour la saisie du mot de passe). De ce fait, on est un
peu coincé pour passer root.
Il existe une solution (que j'ai bien sûr trouvé après avoir brutalement redémarrer le serveur), une simple option à sudo qui permet de lire le mot de passe depuis stdin. Et là, pas besoin d'exécuter la commande dans un terminal donc !
echo "mypassword" |sudo -S id
[sudo] password for rdessort: uid=0(root) gid=0(root) groupes=0(root)
Et comme cela affiche votre mot de passe en clair sur l'écran, voici un petit script pour améliorer la chose :
#!/bin/bash
echo -n "Enter password: "
read -s passwd
ssh serveur-foireux "echo $passwd |sudo -S id"
Une autre application probablement beaucoup plus courante pourrait être de pouvoir scripter des commandes nécessitant d'être root sur le serveur. Notamment exécuter la même commande sur plusieurs dizaines de serveurs d'affilée.