Jak mogę automatycznie zmienić katalog przy logowaniu ssh?

87

Usiłuję uzyskać sshautomatyczną zmianę do określonego katalogu po zalogowaniu. Próbowałem uruchomić to zachowanie, korzystając z następujących dyrektyw w ~/.ssh/config:

Host example.net
LocalCommand "cd web"

ale przy każdym logowaniu widzę:

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

chociaż zdecydowanie jest webfolder w moim katalogu domowym. Nawet użycie bezwzględnej ścieżki daje ten sam komunikat. Żeby było jasne, jeśli piszę cd webpo zalogowaniu, przechodzę do odpowiedniego folderu.

Czego tu brakuje?

EDYTOWAĆ:

Różne kombinacje cytatów / ścieżek bezwzględnych dają różne komunikaty o błędach:

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

To sprawia, że ​​myślę, że cytatów nie powinno tam być i że pojawia się kolejny błąd.

Gareth
źródło
9
LocalCommand jest uruchamiany w systemie lokalnym, a nie w systemie zdalnym.
Steve Kehlet,
Zobacz tutaj superuser.com/a/124110/47962
Nakilon,

Odpowiedzi:

25

cd jest wbudowaną powłoką. LocalCommand jest wykonywany jako:

/bin/sh -c <localcommand>

Tego, czego szukasz, nie można tak naprawdę osiągnąć poprzez SSH; musisz w jakiś sposób zmodyfikować powłokę, np. przez bashrc / bash_profile.

<Edycja prawie dekadę później ...>

LocalCommandw każdym razie nie jest tym, czego chcesz. To działa na twoim komputerze. Chcesz RemoteCommand. Coś takiego działało dla mnie:

Host example.net
  RemoteCommand cd / && exec bash --login
  RequestTTY yes
BMDan
źródło
1
Tak, chciałem tylko o tym wspomnieć. Zamiast tego możesz umieścić cdpolecenie ~/.bashrcna zdalnym serwerze.
vdboor,
To irytujące. Jak wspomniałem w innym komentarzu, serwer ma wiele nazw hostów i chciałem mieć inne zachowanie, w zależności od tego, które zostało użyte. Myślę, że nie można ustalić, który został użyty z .bashrc?
Gareth,
Jest to możliwe, ale prawdopodobnie niewskazane. Coś jak zastąpienie ssh małym skryptem powłoki lub aliasem, który przekazuje nazwę hosta jako zmienną do wyeksportowania (la "ssh -t user @ host 'export connhostname = host; bash --login'"). Ale rzeczywiście zaczynasz wchodzić na bardzo dziwne terytorium. Być może lepszym pytaniem jest: DLACZEGO chcesz tego zachowania?
BMDan,
Szczerze mówiąc, nie jest to aż tak wielka sprawa. Jestem właśnie w sytuacji, w której przez większość czasu loguję się na ten serwer idę prosto do jednego z dwóch katalogów (w zależności od tego, z którego hosta korzystam)
Gareth
77

To działa:

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

Aby utworzyć katalog, jeśli nie istnieje:

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

Jeśli nie dodasz bashdo końca ścieżki, wyjdziesz po uruchomieniu cdkomendy. A jeśli nie dodasz, --loginto twoje ~/.profileźródło nie będzie.

Władysław Leżniew
źródło
To kończy mnie w odpowiedniej lokalizacji, z monitem bash. doskonały!
Peter Ehrlich,
To też działa dla mnie, ale jeśli spróbuję użyć go z ssh jump-host, to nie działa. Otrzymuję komunikat o zamknięciu połączenia.
Riccardo,
43
  1. Zaloguj się do swojego pudełka
  2. Edytować ~/.bash_profile
  3. Na końcu pliku dodaj cd /path/to/your/destination
  4. Zapisz i wyjdź
  5. Wyloguj się z pola
  6. Zaloguj się ponownie i powinieneś wylądować /path/to/your/destination
sobi3ch
źródło
3
Na niektórych komputerach może być konieczne dołączenie cd /path/to/your/destinationdo ~/.bashrczamiast ~/.bash_profile. Wynik powinien być taki sam.
Matthias
Działa to doskonale dzięki - czy ogranicza się tylko do mojego identyfikatora użytkownika, czy wpłynie również na logowanie innych użytkowników?
hard_working_ant
@BabyGroot, jeśli zmodyfikujesz, ~/.bash_profilelub ~/.bashrcwpłynie to tylko na bieżącego użytkownika.
rubenvarela
5

Bardziej niezawodne rozwiązanie w przypadku, gdy trzeba ssh i przesłonić domyślny plik .bashrc. Jest to przydatne w przypadkach, gdy zdalne środowisko serwerowe ma wiele dokumentów i używane przez wielu użytkowników.

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

Bardziej szczegółowe:

  1. Pierwsze polecenie tworzy .bashrc_tmpplik w /tmpkatalogu na zdalnym serwerze z zawartościącd /path/to/dir
  2. Następne polecenie wykonuje się bashz plikiem konfiguracyjnym określonym w kroku 1. Pozwala to na przejście do pożądanego katalogu i pominięcie domyślnego .bashrc.
  3. Całe to polecenie jest zapakowane jako alias, więc w wierszu polecenia klienta ssh można go wywołać jakossh_myserver
Alex Skrypnyk
źródło
Kreatywny ... o ile masz uprawnienia do zapisu w / tmp
smci
4

Czy włączyłeś tę dyrektywę w swojej konfiguracji ssh?

PermitLocalCommand yes

Domyślnie jest to no, w którym przypadku twoja LocalCommanddyrektywa zostanie zignorowana.

Alternatywnie, czy próbowałeś dodać polecenie do swojego .bashrcpliku?

EEAA
źródło
Ta dyrektywa jest ustawiona, tak (i ​​zakładam, że nie zobaczyłbym wyświetlonego komunikatu o błędzie, gdyby nie był). Problem z używaniem .bashrc polega na tym, że serwer ma różne nazwy hostów i chciałbym, aby różne nazwy hostów tłumaczyły na różne katalogi początkowe
Gareth
Jeśli każda nazwa hosta nie ma innego adresu IP, serwer nie będzie wiedział, o którą nazwę hosta prosisz. Podczas gdy żądania HTTP zapewniają przyjazny nagłówek Host: do identyfikacji żądanej nazwy hosta, połączenia SSH nie.
Fosco,
4

Przeszukałem wiele stron internetowych (stackoverflow, ten), ale nie znalazłem tego, czego chciałem. W końcu stworzyłem własny skrypt powłoki. Wklejam to tutaj. Możesz także skopiować go do katalogu w katalogu PATH.

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

Więc po tym. Ja robię:

connect <foldername>

Uwaga: Może być konieczne wylogowanie i ponowne zalogowanie po zmianie zmiennej ścieżki

aryjski
źródło
Wolę to od poprzedniej sugestii, ponieważ „$ SHELL” jest zawsze ważne, a „bash” może nie być. Również użycie „exec” jest miłym akcentem.
Dave
Dalsze udoskonalenie by się upewnić 'cd' jest udany - „cd ~ / 1 $ && exec ...”
Dave
3

W twoim ~/.ssh/config:

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

Na koniec ~/.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

Próbowałem to zrobić za pomocą przekazywania zmiennych, w tym z eksportowaną zmienną, ale te polecenia są uruchamiane w różnych powłokach.

Nawiasem mówiąc, podczas testowania tego, co próbujesz zrobić, nie wystąpił błąd, gdy użyłem nie cytowanej ścieżki bezwzględnej. Dodałem ; pwdna końcu polecenia i wyświetlany jest poprawny katalog, jednak katalog, w którym skończę, to ~. W cdmoich plikach startowych powłoki nie ma poleceń. Próbowałem oddanie inna cd somedir; pwdw ~/.ssh/rc(z drugiej strony nadal na swoim miejscu). configPolecenie jest wykonywane przed motd jest wydawana i rcpolecenia wydawane później, ale przed skorupy pliki startowe są pozyskiwane. Więc znowu dzieje się to w innej powłoce.

Wypróbuj technikę przekazywania plików i daj mi znać, czy to działa.

Dennis Williamson
źródło
2

Czy próbowałeś tego bez cytatów? Jedyne przykłady, które widziałem, nie mają ich, więc przy nich może to być próba wykonania cd \ web jako polecenia.

James L.
źródło
Ok, usunięcie cytatów wydaje się pomagać, ale nadal mam błędy (patrz edytowany post)
Gareth
1

Możesz także spróbować tego z opcją -t:

ssh server -t "cd /my/remote/directory; bash"
kenorb
źródło
1

Spróbuj użyć RemoteCommandzamiast tego, np

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

RemoteCommand: Określa polecenie do wykonania na zdalnym komputerze po udanym połączeniu z serwerem. ( man ssh_config)

kenorb
źródło