Mon équipe est responsable de milliers de machines Linux / Unix, donc naturellement le count root est "partagé" entre les administrateurs. Je préfère le mode vi, d'autres préfèrent le mode emacs.
Comment puis-je définir le mode readline en mode vi sur connection SSH à n'importe quelle machine, sans forcer tous les autres à utiliser le mode vi aussi?
Essentiellement voudrait avoir l'effet de set -o vi
après la connection sans avoir à taper à chaque fois, et sans forcer sur tout le monde (autant que le mode emacs m'ennuie, le mode vi est ennuyeux pour eux).
Je sais que cela ne poserait pas de problème si tout le monde utilisait ses propres counts avec sudo pour exécuter des commands privilégiées, mais en raison de circonstances hors de mon contrôle, ce n'est malheureusement pas une option.
Voici une façon stupide de le faire, qui ne fonctionne vraiment bien qu'avec l'authentification par key publique:
Tout d'abord, assurez-vous que votre machine locale a nc
dessus.
Ensuite, créez un script (je l'appellerai connect-to-server
) sur votre machine locale et placez-le dans un endroit où votre ${PATH}
sait *:
#!/bin/sh # connect-to-server ssh -q server-hostname "touch .yourname" </dev/null >/dev/null 2>&1 nc server-hostname 22
Ensuite, modifiez le .bashrc
sur le système distant pour inclure quelque part:
# partial .bashrc if [ -f "${HOME}/.yourname" ]; then rm "${HOME}/.yourname" set -o vi fi
Enfin, de return dans votre machine locale, éditez ~/.ssh/config
pour append:
# partial ssh config Host serverNickname Hostname server-hostname ProxyCommand connect-to-server
Les inconvénients de cette approche (et pourquoi je l'appelle stupide):
.yourname
pas encore été supprimé. Dans ce cas, ils obtiennent également l' set -o vi
. ssh serverNickname command
, la command
s'exécutera, mais (puisque .bashrc
n'est jamais source), le file .yourname
rest, donc il serait poli d'avoir un second alias dans votre configuration ssh qui n'utilise pas le pseudo -proxy. En fait, le seul avantage de cette approche est que votre command ssh
n'a pas besoin d'argument supplémentaire.
* Si vous ne voulez pas changer quoi que ce soit sur les systèmes distants, voici un pseudo-proxy alternatif qui crée un temporaire .bashrc
:
#!/bin/sh # connect-to-server ssh -q server-hostname 'ln .bashrc .bashrc.real; cat .bashrc.real <(printf "set -o vi; ln -f .bashrc.real .bashrc\n") >.bashrc.yourname; ln -f .bashrc.yourname .bashrc' </dev/null >/dev/null 2>&1 nc server-hostname 22
Cela a tous les mêmes inconvénients de l'autre méthode, vous voudriez donc toujours un second alias dans votre configuration ssh
qui n'invoque pas le pseudo-proxy.
J'irais pour:
ssh server -t "bash --login -o vi"
mais si vous êtes un administrateur, vous pouvez essayer quelque chose de plus propre. Par exemple, vous pouvez utiliser l'option ssh SendEnv
du côté client pour transmettre une variable spécifique, utiliser AcceptEnv
dans la configuration sshd
(côté server) pour l'accepter et, en fonction de cela, modifier le file .bashrc
la racine pour ajuster le comportement en fonction de la valeur de la variable.
Cela implique de changer la configuration de sshd
sur tous les hôtes ainsi que leur .bashrc
. Pas exactement un "standalone" façon de faire, cependant …
Pour une solution facile côté client:
alias connect='ssh -t root@server "bash -o vi"'
Cela échouera si les scripts d'initialisation du shell de la racine utilisent explicitement set -o emacs
ou définit EDITOR
sur emacs
ou si le file .initrc
la racine invoque les raccourcis keyboard emacs
.
Le rest de cette réponse concerne les solutions côté server.
Cela fonctionne lorsque vous entrez dans la machine, puis utilisez sudo -i
:
Pour votre /root/.bashrc
:
if [[ -n "$SUDO_USER" ]] && [[ -f /root/.bashrc-"$SUDO_USER" ]]; then source /root/.bashrc-"$SUDO_USER" fi
Cela vous permet d'avoir un file bashrc
personnel appelé /root/.bashrc-pasortingck
où vous pouvez faire ce que vous voulez, comme set -o vi
.
En combinant ceci avec une approche quelque peu naïve pour choisir ce file rc en fonction de $SSH_CLIENT
:
if [[ -n "$SUDO_USER" ]]; then person="$SUDO_USER" elif [[ -n "$SSH_CLIENT" ]]; then case "$SSH_CLIENT" in 192.168.216.100*) person="joe" ;; 192.168.216.120*) person="pasortingck" ;; 192.168.216.150*) person="lindsey" ;; esac fi if [[ -n "$person" ]] && [[ -f /root/.bashrc-"$person" ]]; then source /root/.bashrc-"$person" fi
Cela ne fonctionne évidemment que si vous vous connectez à partir de la même adresse IP tout le time …
Une autre approche qui utilise le champ de commentaire de la key SSH particulière que vous utilisez, qui fonctionne si vous transférez l'agent SSH vers le server:
ssh_comment="$( ssh-add -L | grep -f /root/.ssh/authorized_keys | awk '{ print $NF '} | head -n 1 )"
Ceci sélectionne le champ de commentaire de la key que vous avez utilisée pour vous connecter au server. La head -n 1
est là au cas où vous auriez plusieurs de vos keys dans le file authorized_keys
.
Vous pouvez alors utiliser $ssh_comment
pour choisir un file rc à la source, soit directement avec l'approche $SUDO_USER
ci-dessus (dans laquelle le commentaire dans $ssh_comment
peut-être subir un nettoyage s'il s'agit d'un path), soit via une déclaration de case
comme l'approche $SSH_CLIENT
.
Si vous voulez vraiment le faire sans modification côté server, soit:
1) Exécuter quelque chose comme
$ ssh user@host -t 'bash -l -o vi'
Je ne pense pas que la documentation soit trop claire à ce sujet, mais l' -o option
est mentionnée et semble fonctionner.
2) Utilisez attendez:
Le script expect
:
$ cat bashsetup.expect #!/usr/bin/expect -f set user [lindex $argv 0]; set host [lindex $argv 1]; spawn ssh -l $user $host expect "$ " send "set -o vi\n" interact
Rendez-le exécutable et exécutez:
$ ./bashsetup.expect user testhost spawn ssh -l user testhost [motd, blahblah...] user@testhost ~$ set -o vi user@testhost ~$
Cela suppose que vous pouvez vous connecter sans entrer de passwords (pour l'hôte distant ou pour vos keys), sinon le script expect devrait en tenir count. Mais avec beaucoup de machines, vous avez probablement déjà cela. En outre, je m'attendais à un signe dollar et un espace, modifiez cela en fonction de votre message: "# "
peut-être.
Bien que si quelque chose imprimé avant l'invite inclut ces mêmes caractères, vous devrez inclure quelque chose de plus spécifique dans la string attendue.
En outre, ce script ne supporte pas de donner des arguments supplémentaires à ssh
. Si vous voulez exécuter une command explicite, vous n'avez probablement pas besoin de vi-mode, mais si vous avez besoin d'un tunnel de port, cela peut être un problème.
Mais en tout cas, je pense vraiment que cela devrait être résolu sur les systèmes cibles avec des counts séparés ( sudo
ou tout simplement ancien UID 0). La configuration personnalisée serait également utile dans de nombreux autres cas et, en général, vous souhaiteriez définir un set de files de configuration et de variables d'environnement. (Considérez que les administrateurs pourraient ne pas être d'accord sur la valeur de $EDITOR
, ou le contenu de virc
ou autre chose.)
Supprimer également les users serait plus facile avec des counts distincts.
Tout moyen de synchroniser les files sur tous les hôtes résoudrait aussi sortingvialement cela en vous permettant de vous connecter avec quelque chose comme ssh -t user@host 'pasortingcks_shell.sh'
ou ssh -t user@host 'bash --rcfile pasortingck.rc'
.
http://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch08_04.htm