Comment puis-je exécuter un script immédiatement après la connexion via SSH?

24

J'ai commencé à poser cette question mais y ai répondu pendant que je l'avais ouverte. Je vais poster cette question, la suivre avec ma solution et la laisser ouverte à d'autres solutions potentielles.

<histoire>

Je suis un utilisateur de tmux et vim. J'aime le travail à distance sur vim car je n'ai pas à m'inquiéter du fait que les machines de développement Ubuntu se dérobent lorsqu'un film flash me donne une panique au noyau. L'exécution de tmux signifie que les fichiers ouverts m'attendent après le redémarrage et que je peux continuer là où je m'étais arrêté. J'ai eu des problèmes avec vim en cours d'exécution dans une session tmux lorsque je me connecte comme ceci:

ssh example.com -t 'tmux attach'

Les problèmes UTF-8 surgissent qui ne surviennent pas lors du décorticage normal et de la connexion manuelle à une session tmux.

</ backstory>

Je veux donc une méthode réutilisable pour démarrer quelque chose lors de la connexion ssh, qui n'affecte aucune des autres choses que j'ai configurées dans mon .zshrc(ou votre .bashrcsi vous utilisez toujours bash) qui peuvent être requises pour mon environnement de développement, cela n'affecte pas apparaître lorsque je travaille occasionnellement localement sur la même machine.

connrs
la source

Réponses:

13

Lorsque vous exécutez ssh example.com, le démon ssh démarre un shell de connexion pour vous, et le shell de connexion lit votre ~/.profile(ou ~/.bash_profileou ~/.zprofileou ~/.loginselon votre shell de connexion). Lorsque vous spécifiez une commande à exécuter à distance (avec ou sans -t), le démon ssh démarre un shell ordinaire, donc votre .profilen'est pas lu. Remède:

ssh example.com -t '. /etc/profile; . ~/.profile; tmux attach'

La plupart des démons ssh sont configurés pour refuser la transmission des variables d'environnement à l'exception de LC_*. Si le démon ssh le example.compermet, vous pouvez abuser d'une LC_*variable personnalisée pour démarrer automatiquement tmux - mettez ceci dans votre ~/.profile:

if [ -n "$LC_tmux_session" ] && tmux has -t "$LC_tmux_session"; then
  exec tmux attach -t "$LC_tmux_session"
elif [ -n "${LC_tmux_session+1}" ] && tmux has; then
  exec tmux attach
fi

puis connectez-vous avec LC_tmux_session= ssh example.comou LC_tmux_session=session_name ssh example.com.

Cette réponse contient plus d'informations sur le passage des variables d'environnement via ssh.

Gilles 'SO- arrête d'être méchant'
la source
La raison pour laquelle je n'utilise pas ssh example.com -t 'tmux attach'n'est pas parce qu'il a des problèmes de chargement de mon environnement mais parce que j'ai eu des problèmes avec l'affichage des caractères UTF-8; ce problème n'existe pas lors de la connexion de la manière conventionnelle. C'est pourquoi cette question concerne l'exécution de scripts immédiatement après la connexion via SSH.
connrs
J'adore ta solution. Élégant
connrs
@connrs: Avez-vous des problèmes avec UTF-8 même lorsque vous exécutez votre .profile? J'ai supposé que le problème était dû à des paramètres régionaux incorrectement définis sur la machine cible, que vous /etc/profileou .profilecorrigiez. Le problème des paramètres régionaux peut probablement être résolu avec plus d'informations.
Gilles 'SO- arrête d'être méchant'
Je voulais retourner au bureau pour tester cela. Vous avez tout à fait raison, la recherche du profil / etc / déclenche un comportement correct. Vous avez maintenant résolu le problème qui m'a motivé à poser cette question plus générique
connrs
6

J'ai précédemment conseillé de définir PermitUserEnvironment yeset d'ajouter une variable d'environnement dans votre ~/.ssh/environmentjusqu'à ce qu'Eli Heady intervienne avec une meilleure suggestion dans les commentaires ci-dessous.

Ouvrez votre .zlogin(bash: .bash_profileetc.) et mettez ce qui suit:

if [[ "$SSH_CONNECTION" != "" && "$MY_SSH_CONNECTION" != "yes" ]]; then
    while true; do
        echo -n "Do you want to attach to a tmux session? [y/n]"
        read yn
        case $yn in
            [Yy]* ) MY_SSH_CONNECTION="yes" tmux attach; break;;
            [Nn]* ) break;;
            * ) echo "Please answer y/n";;
        esac
    done
fi

Inspiration tirée de: Comment puis-je demander une entrée dans un script shell Linux?

Notez que j'ai utilisé le .zloginfichier mais vous pouvez utiliser votre .zshrcfichier mais j'aime garder mes fichiers dot bien rangés et il les sépare afin que je puisse les utiliser sur d'autres machines.

Remplacez la question par quelque chose qui vous convient et remplacez MY_SSH_CONNECTION="yes" tmux attachpar ce que vous souhaitez exécuter à ce stade.

Notez comment le script définit MY_SSH_CONNECTION="yes"avant tmux attachde le transmettre à tmux car il ouvrira également un shell qui accédera au même script ci-dessus et empêchera toute récursivité.

connrs
la source
2
L'utilisation de PermitUserEnvironment ne sera pas possible dans certains environnements en raison des implications potentielles pour la sécurité. SSH définit la variable $ SSH_CONNECTION, qui peut être utilisée à la place de votre $ SSH_LOGIN dans votre .zlogin, évitant ainsi la nécessité d'utiliser ~ / .ssh / environnement. Quelque chose comme if [[ "$SSH_CONNECTION" != "" ]]ça devrait le faire.
Eli Heady
3

Moi-même, j'ajoute ceci à mes fichiers .bash_profile:

if [ -z "$STY" ]; then
    reattach() { exec screen -A -D -RR ${1:+"$@"} ; }
fi
if [ -t 0 ]; then
    screen -wipe
    echo 'starting screen... (type Ctrl-C to abort)'
    sleep 5 && reattach
fi

Cela me donne un peu de temps pour abandonner la refixation ou la création d'une session d'écran. Cela ne fonctionnera pas sur les formats de «commande système ssh» (qui n'appelle pas le profil ~ /.*). Une fonction shell est configurée pour se rattacher si j'abandonne.

Arcege
la source
Génial! J'ai réussi à corriger cela en mettant bashrc à la place, puis dans chaque nouvelle fenêtre d'écran - lors du passage à .profile, cela a bien fonctionné.
Hugo
0

Vous pourriez envisager de courir

ssh remotehost -t screen -DR

et exécutez votre session de terminal là-bas. Vous pouvez ensuite détacher ( ^A^D) et rattacher plus tard (à partir d'un autre client également). Cela fera disparaître le problème de l'initialisation non interactive car l'écran conserve les sessions de terminal interactives complètes (également les shells d'ouverture de session, man screen(1) ou ^A?)

sehe
la source
Comme mentionné dans ma question, j'utilise tmux plutôt que l'écran GNU pour gérer mes sessions. Et lorsqu'il est chargé, -t 'tmux attach'j'ai des problèmes avec vim qui ne sont pas présents normalement. C'est pourquoi la vraie question concerne l'exécution de scripts sur ssh connect plutôt que la gestion d'écran / session.
Toutes
Désolé, vous avez mentionné tmux mais cela ne voulait rien dire pour moi. Merci d'avoir mentionné un nouvel outil!
sehe
0

Pour parler spécifiquement des problèmes UTF-8, si vous ajoutez

SendEnv LANG

Et $LANGest défini sur quelque chose comme en_US.UTF-8à l'extrémité locale et votre sshd à l'extrémité distante autorise la SendEnvdirective (avec AcceptEnvin sshd_config), le tmux à l'autre extrémité devrait l'honorer. J'ai eu ce problème pendant un certain temps et il a été difficile à résoudre.

Chris W.
la source
0

Si vous souhaitez qu'il s'exécute chaque fois que vous vous connectez, vous pouvez simplement ajouter tmux attachau bas de votre ~/.profileordinateur distant.

les lignes sont floues
la source