Jak mogę odrzucić działający proces i powiązać go z nową powłoką ekranu?


159

Mam uruchomiony program w powłoce SSH. Chcę go zatrzymać i móc cofnąć jego wykonanie po powrocie.

Jednym ze sposobów, jakie o tym pomyślałem, było przeniesienie własności na powłokę ekranu, dzięki czemu działała.

Czy istnieje inny sposób postępowania?


8
Zobacz także Czy mogę nie uruchamiać / przeglądać już rozpoczętego procesu? i polecenie Wznów działające w porzuconej sesji SSH , w której wspomniano o kilku rozwiązaniach opartych na ptrace, których (obecnie) nie wymieniono tutaj.
Gilles

Z pytań takich jak unix.stackexchange.com/a/4039/13496 Słyszę o retty i neercs . Hmmm ... zastanawiam się, czy istnieje coś takiego jak warstwa „ screen tutaj”, zanim następnym razem uruchomię proces, czy w przyszłości stracę górny terminal, co ułatwi powrót do standardowego wejścia / wyjścia / błędu
Marcos

Drugorzędnym / niejawnym problemem w tym pytaniu, którego nie mogę pojąć, jest ... dlaczego powłoka zdecydowała się odrzucić zawieszone zadanie, gdy w tle jest nowsze / właśnie uruchomione zadanie, które nawet nie potrzebuje / czeka na standardowe wejście? Do takiego leczenia się przyzwyczaiłem, więc nie wiem, co tu się zmieniło ...
Marcos,

Odpowiedzi:


86

Korzystanie z GNU screenjest najlepszym rozwiązaniem.

Uruchamianie ekranu uruchomionego przy pierwszym logowaniu - uruchamiam screen -D -R, uruchamiam polecenie i albo je rozłączam, albo zawieszam, CTRL-Za następnie odłączam od ekranu, naciskając CTRL-Awtedy D.

Po ponownym zalogowaniu się do urządzenia połącz się ponownie, uruchamiając screen -D -R. Będziesz w tej samej powłoce co wcześniej. Możesz uruchomić, jobsaby zobaczyć zawieszony proces, jeśli to zrobiłeś, i uruchomić %1(lub odpowiednie zadanie nr), aby ponownie go wysunąć na pierwszy plan.


2
Wow, nie wierzę, że odpowiedź GNU Screen jest obecnie najniżej oceniana. Czy coś brakuje?
Faheem Mitha

1
Być może! Wydaje mi się najlepszy.
Andrew Yochum

1
Patrząc wstecz, wydaje się, że jest to najbardziej bezbolesne rozwiązanie, pod warunkiem, że możesz odpowiednio zaplanować i uruchomić swoje procesy z poziomu środowiska ekranowego. Tak czy inaczej, uczyniłem to oficjalną odpowiedzią!
levesque

28
Myślę, że to nie odpowiada na pytanie. Pytanie zaczyna się od „ Mam uruchomiony program ”. Ta odpowiedź zakłada, że ​​jeszcze nie działa…
Anko

tak, wyraźnie napisał, że chce wziąć udział w sesji ekranowej :-)
Florian Heigl

112

Możesz odwołać „własność” programu z powłoki za pomocą disownwbudowanego:

# press Ctrl+Z to suspend the program
bg
disown

Mówi to jednak powłoce, aby nie wysyłała SIGHUPsygnału do programu po wyjściu z powłoki. Program zachowa dowolne połączenie z terminalem, zwykle jako standardowe strumienie wejściowe, wyjściowe i błędów. Nie ma sposobu, aby ponownie podłączyć je do innego terminala. ( Ekran działa poprzez emulację terminala dla każdego okna, więc programy są dołączone do okna ekranu).


Możliwe jest ponowne dołączenie deskryptorów plików do innego pliku poprzez dołączenie programu do debuggera (tj. Użycie ptrace) i wywołanie go open, duporaz close. Jest na to kilka narzędzi; jest to podchwytliwy proces, a czasem zamiast tego powodują awarię procesu. Możliwości obejmują (linki zebrane od odpowiedzi na Jak mogę wyprzeć proces uruchomiony i powiązać go do nowej powłoce ekranu? I mogę nohup / screen jest już uruchomiony proces? ):


disownusuwa proces z listy kontroli zadań.
ctrl-alt-delor

3
Dlaczego nie disown -h?
Cees Timmerman

@CeesTimmerman To pozostawia pracę w tabeli zadań powłoki, ale jaka jest z tego zaleta?
Gilles

@Gilles: więc możesz nadal fgczy killto i sprawdź, czy to się skończy samo.
Peter Cordes,

Jakie wspomniane narzędzia działają z grupą procesów (np. bzcat a.bz2 | grep text)? Człowiek za reptyrtwierdzi, że nie obsługuje przenoszenia procesów z dziećmi.
dma_k

64

Aby przenieść proces między terminalami lub ponownie podłączyć odrzucony, możesz użyć np . Reptyr .


1
Tak, to uratowało, dzięki! Czytam stronę autora, jak działa lepiej niż podobne lub starsze narzędzia np. dla programów ncurses.
Marcos

4
To jest niesamowite; powinno to rozwiązać problem przyjaciółki polegający na ciągłej utracie pracy, prowadząc ją prosto w ssh, a następnie potrzebując wsiąść do pociągu. „Ups, zapomniałem użyć ekranu. Znowu.”
Adam Katz

3
+1 Chociaż zaakceptowana screenodpowiedź jest oczywiście idealna, w rzeczywistości nie odpowiada na pytanie, które konkretnie wymaga sposobu przeniesienia aktualnie działającego procesu do screenlub podobnego. Zobacz także tę odpowiedź: serverfault.com/a/284795
toksefa

1
Absolutna wygrana na żywo. Pozwoliłem mi ponownie dołączyć do aktualizacji apt dist-upgrade, która czekała na potwierdzenie użytkownika.
andig

28

Moje ulubione rozwiązanie polega na tym tmux, że możesz odłączyć sesję i podłączyć ją ponownie w innym terminalu.

Po odłączeniu się od poprzedniej sesji możesz bezpiecznie zamknąć terminal; później użyj, tmux attachaby wrócić do sesji, nawet jeśli się wylogowałeś.


1
możesz także udostępnić sesję swojemu przyjacielowi, korzystać z wielu okien i paneli i wiele więcej! uwielbiam ^ _ ^
igor

przykład korzystania proszę?
Witalij Zdanevich,

21

Istnieje również małe narzędzie o nazwie retty, które pozwala ponownie podłączyć działające programy do innego terminala.


19

Nie używam go regularnie, ale Neercs twierdzi, że to popiera. Jest to screenpodobny program z różnymi fantazyjnymi funkcjami, takimi jak lepsze zarządzanie panelem, ale najważniejsze, co oferuje, to możliwość zaimportowania procesu do panelu


2
Ciekawy. Odtwarza ptracefunkcję dirty ( ), ale nie tylko manipuluje deskryptorami plików, ale również rozwidla proces. Jest w stanie złapać find /, ale rozbił interaktywne uderzenie.
Gilles

@Gilles Nie pamiętam, jak poszło, kiedy próbowałem, ale nie ma dobrej reputacji, powiedziano mi, że dość regularnie kończy się niepowodzeniem
Michael Mrozek

9

Jeśli chcesz go tylko zatrzymać i uruchomić ponownie później, możesz użyć killz STOPlub CONTsignal.

Najpierw dowiedz się o procesach PID

$ ps aux

Następnie wyślij sygnały do ​​tego PID wymienionego w procesie

$ kill -STOP <PID>

$ kill -CONT <PID>

9

„injcode” z ThomasHabets wydaje się być dokładnie tym, czego potrzebuję:

https://github.com/ThomasHabets/injcode

Program injcode pozwala na wstrzyknięcie dowolnego kodu do uruchomionego procesu, niezależnie od tego, czy wiedziałeś wcześniej i czy uruchomiłeś screen lub tmux

Z pliku README:

Przykład 1: przenieś irssi z jednego terminala do drugiego

Może przenieść to na ekran.

Najpierw uruchom irssi w jednym terminalu.

Uruchom injcode w innym terminalu: $ injcode -m retty

Irssi powinien teraz zostać przeniesiony do drugiego terminala, w tym mając nowy terminal kontrolny.


1

To działało dla mnie:

  1. bg proces
  2. jobs -l znajdź numer procesu
  3. tmux uruchom menedżera okien powłoki
  4. reptyr -L PROCESSNUMBER

reptyr„s -Lbyło konieczne, aby uzyskać to do pracy:

-L Like '-l', but also redirect the child's stdio to the slave.

z powodu tego błędu:

$ reptyr 30622

[-] Unable to open the tty in the child.
Unable to attach to pid 30622: Permission denied

I z -L

$ reptyr -L 30622
Opened a new pty: /dev/pts/4
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.