Uruchom zdalne polecenie ssh z pełną powłoką logowania

48

Chciałbym zrobić coś takiego ssh example.com 'ls'Jednak na stronie ssh:

Jeśli podano polecenie, jest ono wykonywane na zdalnym hoście zamiast powłoki logowania.

Tak więc dzieje się tak, że lswyświetla swoje wyjście, a następnie ssh wychodzi.

Nie mogę zrozumieć, jak otworzyć pełną powłokę logowania, a następnie uruchomić polecenie w tej powłoce. Pozostawienie otwartej powłoki po uruchomieniu polecenia. Jakbym ręcznie wykonał następujące czynności:

  localhost$ ssh example.com 
example.com$ ls
             /folder1 
             /folder2 
example.com$ _

Jakieś pomysły?

Mateusz
źródło
to jest podobne pytanie superuser.com/questions/261617/... ale żadna z odpowiedzi nie wydaje się pasować do tego, co próbuję zrobić.
Matthew
Jak o ssh example.com 'ls;bash'?
Andrejs Cainikovs,
potrzebujesz -i w moich systemach, aby druga powłoka była interaktywna.
Flexo
opcja -t jest odpowiedzią na twoje pytanie. Istnieją inne opcje (na przykład pęku kluczy), ale zależą od twoich rzeczywistych potrzeb, które nie są dla mnie wystarczająco jasne.
hornetbzz
@hornetbzz -t daje mi pseudo-tty. Ale poza tym zachowanie jest takie samo. Chcę uruchomić interaktywną powłokę, uruchomić polecenie wewnątrz tej powłoki i pozostawić powłokę otwartą po uruchomieniu polecenia.
Matthew

Odpowiedzi:

40

Po prostu powiedz bash, aby wykonał, lsa następnie sam w powłoce logowania

$ ssh user@host  -t 'bash -l -c "ls;bash"'
fons
źródło
2
Niestety nie działa to podczas używania screen. W przeciwnym razie wydaje się, że robi to, co próbowałem zrobić.
Mateusz
31
ssh user@host -t 'ls; exec $SHELL -l'

-tWymuś alokację pseudoterminalową. Można to wykorzystać do uruchamiania dowolnych programów ekranowych na zdalnym komputerze. Jest nieco bardziej odpowiedni niż bash -i.

exec Nie jest tworzony nowy proces.

-lszuka ~ / .bash_profile, ~ / .bash_login i ~ / .profile, w tej kolejności oraz odczytuje i wykonuje polecenia z ... Bez tego prawdopodobnie nie można uruchomić skryptów / poleceń z katalogu ~ / bin, ponieważ ten kod z ~ / .profile nie zostanie wykonane bez -lflagi:

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
grawitacja
źródło
@grawity @Alan Może to działać jako obejście, ale naprawdę chciałbym, aby polecenie działało w powłoce, a nie tylko otwierało nową powłokę po uruchomieniu polecenia.
Matthew
+1, -t jest zdecydowanie właściwą drogą do przejścia przez -i, właśnie o tym zapomniałem.
Flexo,
@matthew: Musisz to załatać, bashaby na to pozwolić.
grawity
@ Naprawdę nie bardzo, zobacz moją odpowiedź poniżej
fons
@matthew, użyj exec bashlubexec $SHELL
Eugen Konkov
1

W swoim komentarzu do odpowiedzi fons mówisz, że nie działa podczas używania screen.

Czy mógłbyś to rozwinąć? Patrząc na kod źródłowy openssh, sshd wykonuje polecenie, wywołując

YOUR_DEFAULT_SHELL -c COMMAND

Tak więc, na przykład, jeśli domyślna powłoka jest screen, to nie będzie działać dobrze, bo wszystko, co screen„s -cflag prostu nadpisuje ITS .scrreenrc. Tak więc naprawdę nie ma możliwości wysłania poleceń do ekranu, jeśli jest to domyślna powłoka. Będziesz musiał uruchomić screen jako polecenie wydane ssh, ale z domyślną powłoką, która nie jest screenem .

Jeśli to właśnie próbujesz zrobić, myślę, że wszystko stanie się naprawdę dziwne, ponieważ screenzamknie także okna za pomocą nieinteraktywnych programów, więc będziesz musiał zrobić podobną sztuczkę jak fony, ale o jeden poziom głębiej. SO, z np. / Bin / bash (a nie screen) jako domyślną powłoką Coś takiego:

ssh user@host -t 'screen bash -l -c "ls;bash"'

Który powinien - wziąć głęboki oddech - ssh do hosta, uruchomić bash -c z poleceniem screen, co spowoduje utworzenie nowego okna. Gdyby to okno właśnie otworzyło ls, skończyłoby się, a ekran skończyłby się, więc używamy sztuczki fonsa w nowym oknie ekranu .

Myślę, że to zadziała, jeśli to właśnie próbowałeś zrobić;)

Scott Walls
źródło
Myślę, że problem, z którym mam do czynienia screenw tej sytuacji, polega na tym, że zwykle ładuję go z exec screen -RRmojego .profile. Oznacza to, że bash -lpróbuje załadować ekran, który zrzuca resztę. wygląda na to, że mogę to obejść, usuwając „-l” zarówno w rozwiązaniach twoich, jak i @fons (twoje wtedy mnie zostawia screen). Ale to trochę dziwne.
Matthew
0

Wiele opcji -t wymusza alokację tty, nawet jeśli ssh nie ma lokalnego tty:

ssh -tt user@host 'bash -l -c "/path/to/command'
panticz.de
źródło