SSH et les shells par defaut

Le vendredi 26 février 2016 par Benjamin Boudoir

Parfois, on se retrouve a travailler avec plusieurs personnes sur un compte générique (root, par exemple).

La méthode recommandée consisterait a ce que chaque personne ait un utilisateur et se su -, mais ce n'est pas parce que la méthode est recommandée qu'elle est appliquée.

En tout cas, dans ce genre de cas, on peut se retrouver avec un certain nombre de points agaçants. Notament : le shell par défaut.

Je trouve celui de mes collègues inutilisable, mais chacun ses méthodes de travail.

Toujours est-il qu'il y a de nombreuses méthodes pour utiliser un autre shell :

Méthode 1 : Lancer son shell

Se connecter et taper bash, c'est simple, mais j'en veux pas.

C'est pas automatique et pour peu que le rc précédent joue avec les couleurs, je me retrouve avec un terminal moins lisible.

Méthode 2 : Forced command

On peut forcer une commande de 2 façons :

Dans le ~/.authorized_keys

command="/bin/bash" ssh-rsa ....

En revanche, si vous avez besoin d'utiliser une autre commande comme sftp / rsync / etc. C'est un peu mort.

On va donc pas garder cette solution.

Dans la ligne de commande

me@localhost# ssh host "bash -l"

C'est cool, mais c'est pas très automatisable. Si on avait un switch qui permet de préciser une commande par exemple, on aurait pu s'ajouter un alias. Et c'est compliqué de retraiter tous les arguments en shell script pour ne pas passer cet argument lorsque l'on veut utiliser une autre commande.

Méthode 3 : changement dynamique depuis les rc

C'est la seule façon que j'ai trouvé et qui puisse marcher comme je le veux.

Si vous êtes root sur la machine distante

Commencez par changer la configuration du serveur ssh pour accepter une nouvelle variable de la part de SendEnv.

Par exemple, wantedshell.

Et ajoutez au début de votre RC :

[ -z "$wantedshell" ] && exec $wantedshell --login

Une fois ceci fait, un petit alias dans votre rc en local :

alias ssh='env wantedshell="$SHELL" ssh'

Et voilà !

Si vous n'êtes pas root sur la machine distante

Ça demande de modifier le RC de façon a lire une variable TERM modifiée. Pourquoi TERM ? Parce qu'elle est toujours envoyée, de nombreux programmes ne pourraient pas s'excécuter correctement sans ça.

Les quelques lignes suivantes sont a placer au début du fichier rc chargé par défaut sur la machine distante (~/.bashrc, ~/.profile, ~/.zshrc, ... selon votre configuration) :

echo $TERM | grep -q ':'

if [ "$?" = 0 ]
then
  wantedshell=$(echo "$TERM" | cut -d':' -f 1)
  TERM=$(echo "$TERM" | cut -d':' -f 2)
  export TERM
  exec $wantedshell --login
fi

Une fois ceci fait, un petit alias dans votre rc en local :

alias ssh='env TERM="$SHELL: $TERM" ssh'

Et du coup, vous enverrez dynamiquement le shell que vous souhaitez. Mais si vous oubliez de mettre le premier bloc de code, certains applicatifs pourraient ne pas se lancer parce qu'ils n'ont pas d'information concernant le terminfo que vous présentez.