Czy mogę nohup / screen już rozpoczęty proces?

260

Przeprowadzam kilka testów długoterminowych skryptów migracji danych za pośrednictwem SSH. Powiedzmy, że zaczynam uruchamiać skrypt około 16:00; teraz biegnie szósta po południu i przeklinam siebie, że nie zrobiłem tego wszystkiego screen.

Czy jest jakiś sposób na „wsteczną” nohupprocedurę, czy też muszę pozostawić komputer przez całą noc? Jeśli nie można dołączyć screendo nohupprocesu, który już rozpocząłem, to dlaczego? Ma to coś wspólnego z interakcją procesów rodzic / dziecko? (Nie przyjmuję odpowiedzi „nie”, która przynajmniej nie odnosi się do pytania „dlaczego” - przepraszam;))

ojrac
źródło
4
Właśnie zobaczyłem interesujący post na blogu disown. blogs.oracle.com/ksplice/entry/disown_zombie_children_and_the
ojrac

Odpowiedzi:

212

Jeśli używasz Bash, możesz uruchomić disown -h job

zapierać się

disown [-ar] [-h] [jobspec ...]

Bez opcji każdy typ zadania jest usuwany z tabeli aktywnych zadań. Jeśli -hpodano opcję, zadanie nie jest usuwane z tabeli, ale jest oznaczane, aby SIGHUP nie był wysyłany do zadania, jeśli powłoka otrzyma SIGHUP. Jeśli specyfikacja zadania nie jest obecna i nie podano opcji -anor -r, używane jest bieżące zadanie. Jeśli nie podano specyfikacji zadania, -a opcja oznacza usunięcie lub zaznaczenie wszystkich zadań; -ropcja bez jobspec argumentu ogranicza działanie z prowadzeniem pracy.

gharper
źródło
Niesamowite; Miałem nadzieję, że coś takiego się pojawi.
ojrac
7
Życie może być niesprawiedliwe. gharper i ja pisaliśmy to mniej więcej w tym samym czasie :)
serverhorror
4
Jesteś moim bohaterem
Thomas Dignan,
9
disown nie jest specyficzny dla bash. Jest również w zsh, ksh93, ...
Phil P
2
Okazało się, że rzeczywiście trzeba użyć disown %1, jeśli 1 jest jobspec, w przeciwieństwie fg lub bg gdzie wystarczy użyć bg 1 serverwatch.com/tutorials/article.php/3935306/...
mltsy
81

Użyj reptyr

Z pliku README:

reptyr - A tool for "re-ptying" programs.
-----------------------------------------

reptyr is a utility for taking an existing running program and
attaching it to a new terminal. Started a long-running process over
ssh, but have to leave and don't want to interrupt it? Just start a
screen, use reptyr to grab it, and then kill the ssh session and head
on home.

USAGE
-----

  reptyr PID

"reptyr PID" will grab the process with id PID and attach it to your
current terminal.

After attaching, the process will take input from and write output to
the new terminal, including ^C and ^Z. (Unfortunately, if you
background it, you will still have to run "bg" or "fg" in the old
terminal. This is likely impossible to fix in a reasonable way without
patching your shell.)

Kilka postów na blogu autora:

Jonathan Tran
źródło
Będę trzymać się wbudowanych narzędzi (tj. Disown), ale nie jest to tak elastyczne jak reptyr. +1
ojrac
22

Aby ukraść proces z jednego tty do obecnego tty, możesz spróbować tego hacka:

http://www.ucc.asn.au/~dagobah/things/grab.c

Potrzebuje trochę przeformatowania, aby skompilować do aktualnych wersji Linux / glibc, ale nadal działa.

Juliano
źródło
1
Wyjątkowo fajne.
ojrac
16

Kiedy proces się rozpoczyna, STDIN, STDOUT i STDERR są połączone z czymś . Zasadniczo nie można tego zmienić po uruchomieniu polecenia. W opisywanym przypadku prawdopodobnie jest to tty związane z sesją ssh. nohup po prostu nie robi ...

command < /dev/null > nohup.out 2>&1

Oznacza to, że ustawia STDIN na / dev / null, STDOUT na plik, a STDERR na STDOUT. Screen robi znacznie bardziej wyrafinowane rzeczy, polegające na konfigurowaniu tty, które kierują do siebie.

Nie znam żadnego sposobu, aby z mocą wsteczną powstrzymać lub przejrzeć działający proces. Jeśli cd do / proc / $ pid / fd i zobaczysz, na co wskazują 0, 1 i 2.

Możesz mieć szczęście z odrzuceniem, ale nie, jeśli proces spróbuje cokolwiek zrobić przy pomocy STDIN, STDOUT lub STDERR.

freiheit
źródło
2
+1 za dobre komentarze. st (din | out | err) to druga połowa problemu i doceniam radę, od czego zacząć, kiedy następnym razem będę w tym jamie.
ojrac
6
Możesz to zmienić w większości Uniksów. To obrzydliwy hack. Kocham to. :) Po prostu połącz się z procesem za pomocą obsługi debugowania, takiej jak ptrace, a następnie zmuś proces do wywołania dup2 () w celu ponownego połączenia 0,1,2 z innym uchwytem pliku.
Zan Lynx,
2
tak, możesz to zmienić. Obejmuje wstrzymywanie procesu (SIGSTOP) i modyfikowanie deskryptorów plików dla fd 0, 1, 2. Następnie restartowanie (SIGCONT).
Michael Martinez
13

Cryopid jest dalszym rozwinięciem autora grab.c, który zamraża proces do pliku, który następnie uruchamiasz (na ekranie), aby wznowić proces.

TRS-80
źródło
1
Miły! Próbowałem użyć kriopidu w rozprawie magisterskiej na temat migracji procesów, ale to nie działało przez cały czas, bez względu na to, co zrobiłem. W końcu musiałem użyć dynckpt ze starą wersją Linuksa. Czy jesteś prawdopodobnie zaangażowany w rozwój kriopidów? Widzę, że twoje imię jest podobne do domeny autora.
Juliano
1
Nie jestem zaangażowany w rozwój, po prostu znam autora z uniwersytetu. W tej chwili nie ma czasu na utrzymanie kriopidów, więc wygląda na to, że niektórzy zaczęli nad nim pracować na shareources.org/project/cryopid
TRS-80,
12

Mogę tylko dać ci proste „Nie” bez powodu, dla której części ekranu, sam byłbym zainteresowany powodem.

Jakkolwiek próbowałeś disown(wbudowane bash)

~ $ echo $SHELL
/bin/bash
~ $ type disown
disown is a shell builtin
~ $ help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.
Serverhorror
źródło
9

nohup w Solaris / OpenSolaris ma flagę -p, aby nie uruchamiać uruchomionego procesu - na przykład zobacz stronę podręcznika nohup Solaris 10 .

alanc
źródło
5

Niedawno zobaczyłem link do neercs , który jest narzędziem ekranowym zbudowanym przy użyciu libcaca, kolorowej biblioteki ascii-art. Między innymi oferuje możliwość przechwycenia istniejącego procesu i ponownego nadania go w ramach sesji neercs (screen).

Jednak nie użyłem go, więc nie mogę komentować, czy to działa, czy nie.

Daniel Lawson
źródło
2

Prawdopodobnie nie myślę o tym, więc nie krępuj się mnie poprawić (już dowiedziałem się o disown!) ... Czy kombinacja klawiszy Ctrl-Z i „bg” nie działałaby przynajmniej w celu uruchomienia procesu w tle? A może kluczowym problemem jest to, że nadal chciałbyś widzieć STDOUT podczas działania?

Chris_K
źródło
1
To wciąż zabija proces, gdy umiera tty będący właścicielem, więc OP musi zostawić skrzynkę, w której zainicjował polecenie, i tego chce uniknąć
serverhorror
OK, kupię to. Dziękuję za wyjaśnienie. Więc odrzucone -h sugestie z pewnością wyglądają o wiele mądrzejsze niż moje :-)
Chris_K
1
Nadal możesz to zrobić, zaraz po tym, jak będziesz musiał się
zrzec
2

Jeśli możesz żyć z niemożnością interakcji z procesem i nie sprzeciwisz się ładowaniu losowych modułów jądra, możesz zrobić coś gorszego niż patrzeć na Snoop . Alternatywnie istnieje kilka innych projektów. Oto jedno wywołanie injcode, które może w większości robić to, co chcesz.

David Pashley
źródło
1

Chciałem użyć nohup(lub podobnego), aby uruchomić linksprzeglądarkę wiersza polecenia i dołączyć się do niej po pobraniu pliku ze strony internetowej ASP.NET ze skomplikowanym procesem uwierzytelniania i wieloma stanami ukrytego widoku, które utrudniały wykonanie zadania z curl/ wget.

W końcu skończyłem z użyciem, tmuxktóre rozwiązało pracę po prostu świetnie:

  1. Biegać tmux
  2. Uruchom aplikację ( linksw moim przypadku) i pozostaw ją uruchomioną
  3. Zamknij sesję SSH, aplikacja pozostanie uruchomiona
  4. Połącz się za pomocą SSH z tym samym komputerem później i uruchom, tmux attachaby przywrócić aplikację do ekranu
Dmitrij Gusiew
źródło
tmux jest świetny - ale, podobnie jak nohup lub screen, działa tylko wtedy, gdy używasz go przed rozpoczęciem procesu. To pytanie dotyczy czasów, w których zdajesz sobie sprawę, że potrzebujesz tmux po zakończeniu procesu.
ojrac
-1

Czy martwisz się przekroczeniem limitu czasu sesji? W takim przypadku możesz Ctrl-Z i bg proces, a następnie po prostu włożyć coś, co utrzyma sesję przy życiu, np. „Ping -t localhost” lub „top”.

Jeśli chcesz się wylogować, obawiam się, że nie mogę dodać do innych komentarzy.

TrojanName
źródło
To jest wylogowanie.
ojrac
1
Innym sposobem, aby zatrzymać to odłączanie, jest uruchomienie na górze. To zawsze tasuje kilka bajtów.
Rory,