Comment puis-je changer automatiquement de répertoire sur la connexion SSH?

87

J'essaie de passer sshautomatiquement à un répertoire particulier lorsque je me connecte. J'ai essayé de résoudre ce problème en utilisant les directives suivantes ~/.ssh/config:

Host example.net
LocalCommand "cd web"

mais chaque fois que je me connecte, je vois ce qui suit:

/bin/bash: cd web: No such file or directory

bien qu'il y ait définitivement un webdossier dans mon répertoire personnel. Même en utilisant un chemin absolu donne le même message. Pour être clair, si je tape cd webaprès la connexion, je suis dans le bon dossier.

Qu'est-ce que j'oublie ici?

MODIFIER:

Différentes combinaisons de guillemets / chemins absolus donnent différents messages d'erreur:

LocalCommand "cd web"
/bin/bash: cd web: No such file or directory

LocalCommand cd web
/bin/bash: line 0: cd: web: No such file or directory

LocalCommand cd /home/gareth/web
/bin/bash: line 0: cd: /home/gareth/web: Input/output error

Cela me fait penser que les citations ne devraient pas être là et qu'il se produit une autre erreur.

Gareth
la source
9
LocalCommand est exécuté sur votre système local, pas sur le système distant.
Steve Kehlet
Voir ici superuser.com/a/124110/47962
Nakilon

Réponses:

25

cd est un shell intégré. LocalCommand est exécuté en tant que:

/bin/sh -c <localcommand>

Ce que vous cherchez à faire ne peut pas vraiment être accompli via SSH; vous devez modifier le shell d’une manière ou d’une autre, par exemple via bashrc / bash_profile.

<Montage presque une décennie plus tard ...>

LocalCommandce n'est pas ce que tu veux, de toute façon. C'est exécuté sur votre machine. Vous voulez RemoteCommand. Quelque chose comme ça a fonctionné pour moi:

Host example.net
  RemoteCommand cd / && exec bash --login
  RequestTTY yes
BMDan
la source
1
Oui, je voulais juste mentionner à même. Vous pouvez à la place placer la cdcommande ~/.bashrcsur le serveur distant.
vdboor
C'est ennuyeux. Comme je l'ai mentionné dans un autre commentaire, le serveur a un certain nombre de noms d'hôte et je voulais avoir un comportement différent en fonction du type utilisé. Je suppose qu'il n'est pas possible de déterminer lequel a été utilisé à partir de .bashrc?
Gareth
C'est possible, mais probablement pas conseillé. Par exemple, remplacer ssh par un petit script shell ou un alias transmettant le nom d'hôte en tant que variable à exporter (par exemple, "ssh -t utilisateur @ hôte" export connhostname = hôte; bash --login '"). Mais vous commencez à entrer dans un territoire très étrange, en effet. Peut-être une meilleure question est: POURQUOI voulez-vous ce comportement?
BMDan
Pour être honnête, ce n'est pas vraiment un gros problème. Je suis juste dans le cas où la grande majorité du temps que je me connecte à ce serveur, je me dirige directement vers l'un des deux répertoires (en fonction de l'hôte utilisé)
Gareth
77

Cela marche:

ssh server -t "cd /my/remote/directory; bash --login"

Pour créer un répertoire s'il n'existe pas:

ssh server -t "mkdir -p newfolder; cd ~/newfolder; pwd; bash --login"

Si vous n'ajoutez pas bashà la fin du chemin, vous quittez après l' cdexécution de la commande. Et si vous n’ajoutez pas, --loginvotre ~/.profilesource ne provient pas.

Vladislav Lezhnev
la source
Cela me termine au bon endroit, avec une invite bash. parfait!
Peter Ehrlich
Cela fonctionne aussi pour moi, mais si j'essaie de l'utiliser avec ssh jump-host, cela ne fonctionne pas. Je reçois un message de connexion fermée.
Riccardo
43
  1. Connectez-vous à votre boîte
  2. Modifier ~/.bash_profile
  3. À la fin du fichier, ajoutez cd /path/to/your/destination
  4. Enregistrez-le et quittez
  5. Déconnexion de la boîte
  6. Connectez-vous à nouveau et vous devriez atterrir sur /path/to/your/destination
sobi3ch
la source
3
Sur certaines machines, vous devrez peut-être ajouter cd /path/to/your/destinationà ~/.bashrcau lieu de ~/.bash_profile. Le résultat devrait être le même.
Matthias
Cela fonctionne parfaitement, merci - est-ce limité à mon identifiant utilisateur ou cela affectera-t-il également les connexions d'autres utilisateurs?
hard_working_ant
@BabyGroot si vous modifiez ~/.bash_profileou ~/.bashrcn'affectera que l'utilisateur actuel.
rubenvarela
5

Solution plus robuste pour le cas où vous avez besoin de ssh et de remplacer le fichier .bashrc par défaut. Ceci est utile dans les cas où l'environnement de serveur distant a plusieurs docroots et utilisé par plusieurs utilisateurs.

alias ssh_myserver='ssh server_name -t "echo cd /path/to/desired/dir>/tmp/.bashrc_tmp; bash --rcfile /tmp/.bashrc_tmp"'

Plus détaillé:

  1. La première commande crée un .bashrc_tmpfichier dans le /tmprépertoire sur le serveur distant avec un contenucd /path/to/dir
  2. La commande Next s’exécute bashavec le fichier de configuration spécifié à l’étape 1. Cette opération permet de basculer sur le répertoire souhaité et de supprimer les valeurs par défaut .bashrc.
  3. Toute cette commande est encapsulée dans une aliasinvite de commande client ssh, elle peut donc être appeléessh_myserver
Alex Skrypnyk
la source
Créatif ... aussi longtemps que vous avez écrit des permanentes sur / tmp
smci
4

Avez-vous activé cette directive dans votre configuration ssh?

PermitLocalCommand yes

La valeur par défaut pour cela est no, auquel cas votre LocalCommanddirective serait ignorée.

Sinon, avez-vous essayé d'ajouter la commande à votre .bashrcfichier?

EEAA
la source
Cette directive est définie, oui (et je suppose que je ne verrais pas le message d'erreur affiché s'il ne l'était pas). Le problème avec l'utilisation de .bashrc est que le serveur a des noms d'hôte différents, et j'aimerais que différents noms d'hôte soient traduits vers différents répertoires de départ
Gareth
À moins que chaque nom d'hôte ait une adresse IP différente, le serveur ne pourra pas savoir quel nom d'hôte vous avez demandé. Alors que les requêtes HTTP fournissent un en-tête Host: convivial pour identifier le nom d'hôte demandé, les connexions SSH ne le font pas.
Fosco
4

J'ai donc cherché beaucoup de sites Web (stackoverflow, celui-ci) mais je n'ai pas trouvé ce que je voulais. J'ai fini par créer mon propre script shell. Je le colle ici. Aussi, vous pouvez copier un répertoire dans $ PATH.

#!/bin/bash
ssh -t <username@hostname> "cd ~/$1; exec \$SHELL --login"

Donc après ça. Je fais:

connect <foldername>

Remarque: vous devrez peut-être vous déconnecter et vous reconnecter après avoir modifié la variable de chemin d'accès.

aryen
la source
Je préfère cela à la suggestion précédente car '$ SHELL' est toujours valide, alors que 'bash' peut ne pas l'être. Aussi, l'utilisation de 'exec' est une belle touche.
Dave
Un raffinement supplémentaire serait d’assurer le succès de "cd" - "cd ~ / $ 1 && exec ..."
Dave
3

Dans votre ~/.ssh/config:

LocalCommand echo '/home/%r/some/subdir' > /home/%r/.ssh/ssh_cd

A la fin de votre ~/.bashrc:

if [[ -f $HOME/.ssh/ssh_cd ]]
then
    cd $(<$HOME/.ssh/ssh_cd)
    # uncomment the line below and the file will be removed so the cd won't work
    # unless the file is regenerated since you may not want this to operate for
    # non-ssh logins or for ssh logins that you want to function differently
    # rm $HOME/.ssh/ssh_cd
fi

J'ai essayé de faire cela en passant des variables, y compris avec une variable exportée, mais ces commandes sont exécutées dans des shells différents.

En passant, en testant ce que vous essayiez de faire, je n'ai pas eu d'erreur lorsque j'ai utilisé le chemin absolu non indiqué. J'ai ajouté ; pwdà la fin de la commande et le bon répertoire est affiché, mais le répertoire dans lequel je me trouve est ~. Il n'y a pas de cdcommandes dans mes fichiers de démarrage du shell. J'ai essayé de mettre un différent cd somedir; pwddans ~/.ssh/rc(avec l'autre toujours en place). La configcommande est exécutée avant que motd soit émis, puis rcaprès, mais avant la création des fichiers de démarrage du shell. Encore une fois, cela se passe dans une coquille différente.

Essayez la technique de passe par fichier et laissez-moi savoir si cela fonctionne pour vous.

Dennis Williamson
la source
2

L'avez-vous essayé sans les guillemets? Les seuls exemples que j'ai vus ne les ont pas, ils pourraient donc essayer d'exécuter cd \ web en tant que commande.

James L
la source
Ok, supprimer les guillemets semble aider, mais il me reste des erreurs (voir article modifié)
Gareth
1

Vous pouvez aussi essayer ceci avec l'option -t:

ssh server -t "cd /my/remote/directory; bash"
Kenorb
la source
1

Essayez d'utiliser à la RemoteCommandplace, par exemple

Host myhost
  HostName IP
  User ubuntu
  IdentityFile ~/.ssh/id_rsa
  RemoteCommand cd web; $SHELL -il

RemoteCommand: Spécifie une commande à exécuter sur la machine distante après une connexion réussie au serveur. ( man ssh_config)

Kenorb
la source