W ssh, w jaki sposób można uruchomić polecenie na zdalnym komputerze bez wychodzenia?

29

Normalnie, jeśli przekażesz polecenie ssh w ten sposób

ssh [email protected] 'some-command.sh'

Otrzymujesz nieinteraktywną sesję i ssh kończy się, gdy tylko polecenie (lub skrypt lub cokolwiek innego) zostanie uruchomione. Jak mogę uzyskać sesję interaktywną, a jednocześnie uruchomić polecenie, które określiłem na moim komputerze lokalnym? Na przykład chciałbym móc otworzyć ekran i zrestartować określoną sesję ekranu:

ssh [email protected] 'screen -r 12345'

ale nie jest to dozwolone, zwracając błąd „Musi być podłączony do terminala”. co, jak zakładam, oznacza w zasadzie „należy wywołać to polecenie z interaktywnej powłoki”.

Jako kolejny przykład używam mnóstwa maszyn w pracy, które często wymagają ode mnie korzystania ze wspólnego konta, aby mieć prawa do robienia pewnych rzeczy (tak, wiem: zły pomysł, ale nie obwiniaj mnie, nie ustawiłem rzeczy, które sposób) i zwykle mają domyślną powłokę ksh. Chciałbym się zalogować, przełączyć na bash (lub zsh) i pobrać plik .bash_profile (lub .zshrc) z mojego konta. Byłoby to łatwe, gdybym mógł ustanowić interaktywną sesję ssh i przekazać polecenie zdalnej maszynie, aby uruchomiło się po zalogowaniu.

Mam na myśli bardzo nieprzyzwoite (i niesprawdzone) rozwiązanie, które opublikuję, ale mam nadzieję, że ktoś zna lepszy sposób.

AKTUALIZACJA: dla tych, którzy nie zdawali sobie z tego sprawy, nie planuję robić tego wszystkiego ręcznie, więc powiedzenie mi, aby otworzyć sesję interaktywną, a następnie zrobić to ręcznie, w rzeczywistości nic nie rozwiązuje.

2. AKTUALIZACJA: Próbuję jeszcze raz wyjaśnić: próbuję uruchomić (dowolne) polecenia na serwerze (programowo określone na kliencie), ale potem mam otwartą sesję interaktywną, na którą wpływ mają wszystkie polecenia programowe.

ikonoklasta
źródło
echo "command" | ssh user@remote_host
laggingreflex
2
Czy przegapiłeś część pytania „bez wychodzenia”? Jestem całkiem pewien, że zakończy się po zakończeniu polecenia.
iconoclast

Odpowiedzi:

26

Możesz wypróbować następującą komendę, aby uruchomić bash i uzyskać własny profil podczas ssh:

ssh  -t hostname "bash --rcfile ~user/.bashrc"
dogbane
źródło
4
+1. -tPrzełącznik rozwiązuje problemu pytającego jest z screenrównież.
Łaty
3
Czy można tego używać z dowolnymi poleceniami bez zamykania połączenia? Jeśli spróbuję ssh -t www.dev "echo 'hi there'", połączenie zostanie natychmiast zamknięte po wykonaniu polecenia.
iconoclast
11

Opierając się na odpowiedzi dogbane, kompletne rozwiązanie wygląda następująco:

ssh -t user@server 'cd /a/great/place; bash'

Tutaj używam -tdo wymuszenia alokacji pseudoterminalu, która jest wymagana dla interaktywnej powłoki. Następnie wykonuję dwa polecenia na serwerze: najpierw to, co chciałem zrobić przed otwarciem powłoki interaktywnej (w moim przypadku zmiana katalogu na określony folder), a następnie samą powłokę interaktywną. bash widzi, że ma pseudo-terminal i reaguje interaktywnie.

Pojedyncze cudzysłowy zapewniają, że cała rzecz jest przekazywana do zdalnego serwera jako polecenie uruchamiane przez domyślną powłokę.

Jeszcze raz dziękuję dogbane za dostarczenie niezbędnej wskazówki -t. Kiedyś rozwiązywałem ten problem expect, którym jest na pewno zabicie myszy armatą. (:

użytkownik1179239
źródło
2

Wypróbuj to rozwiązanie.

echo "command" | ssh user@remote_host

Logowanie jest interaktywne, a twoje polecenie jest przekazywane tak, jakbyś wpisał je w interaktywnym wierszu poleceń. Sesja kończy się tak, jakbyś wpisał

ssh user@remote_host 'command'
użytkownik210540
źródło
3
Jeśli sesja zakończy się po zakończeniu polecenia, to nie odpowiada na pytanie. Cały punkt polecenia powinien pozostać w interaktywnej sesji po wykonaniu polecenia, a nie tylko poprzez wysyłanie poleceń do serwerów ssh.
iconoclast
Jest to co najmniej dobre do symulacji interakcji dla wykonania polecenia bez użycia -tlub własnego pliku bash. +1
laggingreflex
0

Użyj ssh -X, aby użyć cmd termIO.

Ponadto - możesz połączyć swoje cmd jak „ssh 'source ~ / .bashrc && cd && do” ”

etrbunny
źródło
ale po zakończeniu całego łańcucha nie mam już interaktywnej sesji, prawda? Nadal się zamyka, prawda?
iconoclast
A czy chciałbyś opracować rozwiązanie termIO?
iconoclast
0

dlaczego nie zainstalować Odłącz na zdalnym systemie i użyj:

ssh -t [email protected] "/home/user/bin/detach ls"
Dan D.
źródło
czy to uruchomi się „ls”, a następnie pozostawi mnie z interaktywną sesją? Co jeśli zamiast „ls” uruchamiam „source .somefile”, aby uzyskać aliasy i funkcje. Czy będą one dostępne w mojej interaktywnej sesji, czy też będą prowadzone w ramach innej sesji?
iconoclast,
Nie, z powodu detach, lsnie przechowuje sesję otwartą i odłączać bez drukowania wyjście lsale to nadal prowadzony.
Dan D.
Próbuję uruchomić (dowolne) komendy na serwerze (programowo określone na kliencie), ale potem mam otwartą sesję interaktywną, na którą wpływ mają cokolwiek zrobione przez te komendy programowe. Więc jeśli dobrze cię rozumiem, to mi nie pomaga.
iconoclast
0

Odpowiedź laggingreflex jest bliska ... Zmieniłbym to w następujący sposób:

echo "command\n$(cat -)" | ssh user@remote_host

Niestety, prawdopodobnie nie spodoba ci się sposób, w jaki to działa, ponieważ „cat” buforuje wiersze, które wypisuje na standardowe wyjście ... Jeśli stworzymy skrypt o nazwie „echo-cat”, który wygląda mniej więcej tak:

{
  echo "${@}"
 #cat buffers & won't flush to stdout immediately
 #cat -
  IFS='\n'
  while read line
  do
        echo "${line}"
  done
}

uzyskamy ten sam wynik bez buforowania:

echo-cat "command" | ssh user@remote_host

To prawdopodobnie zbliży Cię do celu ...

Rachunek
źródło
0

To jest kludgey i niesprawdzone, ale myślę, że powinno działać.

Utwórz skrypt o nazwie (np.) Zdalny starter, który pobiera cytowany argument po argumencie użytkownik @ host:

remote-starter [email protected] 'some-command.sh arg1 arg2'

Skrypt ten powinien najpierw zapisać cytowane polecenie (bez cudzysłowów) w pliku o nazwie (np.) .onetimeNa zdalnym komputerze, a następnie uruchomić zwykłe polecenie ssh, tym razem nie przekazując żadnego polecenia do uruchomienia na zdalnym komputerze. (Jeśli uruchamiasz ssh uż[email protected] z poziomu skryptu, może działać uruchomienie exec ssh uż[email protected]).

Aby to zadziałało, komputer zdalny musi .onetimepobierać źródła z pliku .bash_profile lub .zshrc lub cokolwiek innego. Po uruchomieniu .onetimepowinien zostać usunięty .onetime, aby plik nie był uruchamiany następnym razem, gdy wykonujesz regularne logowanie.

ikonoklasta
źródło