Jak rozpocząć i zapomnieć o podprocesie?


Mam długi proces uruchomiony i potrzebuję go do uruchomienia innego procesu (który również będzie działał przez dłuższy czas). Po prostu muszę to uruchomić, a potem zupełnie o tym zapomnieć.
Udało mi się zrobić to, czego potrzebowałem, zbierając kod z książki Programming Ruby, ale chciałem znaleźć lepszy/poprawny sposób i zrozumieć, co się dzieje. Oto, co otrzymałem na początku:
exec("whatever --take-very-long") if fork.nil?
Process.detach($$)
<del>
Czy tak jest, czy jak inaczej mam to zrobić?
</del>Po sprawdzeniu odpowiedzi poniżej otrzymałem ten kod, który wydaje się mieć więcej sensu

:
(pid = fork) ? Process.detach(pid) : exec("foo")
Byłbym wdzięczny za wyjaśnienie, jak działa
fork
. [już zrozumiałem]
Czy odłączenie
$$
było prawidłowe? Nie wiem, dlaczego to działa i naprawdę chciałbym lepiej zrozumieć sytuację.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Alnitak ma rację. Oto jaśniejszy sposób na zapisanie go bez znaku $$
pid = Process.fork
if pid.nil? then
# In child
exec "whatever --take-very-long"
else
# In parent
Process.detach(pid)
end

Celem odłączenia się jest po prostu powiedzenie: „Nie obchodzi mnie, kiedy dziecko się kończy”, aby tego uniknąć

Procesy zombie.
http://en.wikipedia.org/wiki/Zombie_process
.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Funkcja
fork
dzieli proces na dwie części.

Wtedy obie

proces uzyskać wynik funkcji. Dziecko otrzymuje zero/
nil
(i dlatego wie, że jest dzieckiem), a rodzic otrzymuje PID dziecka.
W konsekwencji:
exec("something") if fork.nil?

spowoduje, że dziecko zacznie „coś”, a rodzic będzie kontynuował tam, gdzie był.
Zwróć uwagę, że
exec ()

zastępuje

bieżący proces na „coś”, więc proces potomny nigdy nie wykona żadnego kolejnego kodu Rubiego.
Wywołanie
Process.detach ()
wygląda na nieprawidłowe. Spodziewałbym się, że będzie zawierał PID dziecka, ale jeśli poprawnie odczytam twój kod, to faktycznie odłącza proces nadrzędny.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Odłączanie
$$
było nieprawidłowe. Od s. 348 kilofów (wyd. 2):

$$
Fixnum numer procesu uruchomionego programu. [r/o]

Ta sekcja, „Zmienne i stałe” w rozdziale Język Ruby, jest bardzo przydatna do dekodowania różnych krótkich stałych
$
ruby ​​- jednakże wersja online (najpierw
W rzeczywistości oddzieliłeś program od siebie, a nie z jej dziecka.
Jak powiedzieli inni, prawidłowym sposobem odłączenia się od dziecka jest użycie pid dziecka zwróconego z
fork ()
.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Inne odpowiedzi są dobre, jeśli jesteś pewien, że chcesz odłączyć proces potomny. Jeśli jednak nie masz nic przeciwko lub wolisz przypiąć proces podrzędny (na przykład uruchamiasz podserwery/usługi dla aplikacji internetowej), możesz użyć następującego skrótu
fork do
exec('whatever --option-flag')
end

Podanie bloku nakazuje forkowi wykonanie tego bloku (i tylko tego bloku) w procesie potomnym, kontynuując w obiekcie nadrzędnym.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

znalazłem odpowiedzi powyżej, zepsułem terminal i zepsułem dane wyjściowe. oto rozwiązanie, które znalazłem.
system("nohup ./test.sh &")

Na wszelki wypadek, jeśli ktoś ma ten sam problem, moim celem było wejście na serwer SSH, a następnie kontynuować ten proces, aby pracować nieskończenie. Więc test.sh jest
#!/usr/bin/expect -f
spawn ssh host -l admin -i cloudkey
expect "pass"
send "superpass\r"
sleep 1000000

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się