2010-06-22 20 views
5

Mam skrypt perl, skrypt.pl, który po uruchomieniu wykonuje rozwidlenie, proces rodzicielski wyprowadza swój pid do pliku, a następnie kończy działanie podczas procesu potomnego wyprowadza coś do STOUT, a następnie przechodzi w pętlę while.widelec perl nie działa poprawnie po uruchomieniu zdalnie (przez ssh)

$pid = fork(); 

if (! defined $pid) 
{ 
    die "Failed to fork."; 
} 
#Parent process 
elsif($pid) 
{ 
    if(!open (PID, ">>running_PIDs")) 
    { 
     warn "Error opening file to append PID"; 
    } 
    print PID "$pid \n"; 
    close PID; 
} 
#child process 
else 
{ 
    print "Output started"; 

    while($loopControl)  
    { 
      #Do some stuff 
    } 
} 

Działa to dobrze, gdy nazywam go lokalnie, czyli: perl script.pl.

Skrypt wypisuje niektóre rzeczy, a następnie zwraca kontrolę z powrotem do powłoki. (podczas gdy proces potomny przechodzi w swoją pętlę w tle).

Jednak, kiedy nazywają to poprzez kontrolę ssh nigdy nie powrócił do powłoki (nie jest „Wyjście rozpoczęła” linia kiedykolwiek wydrukowane

tj. $ ssh [email protected] „perl skrypt. pl”

jednak, co ciekawe, proces dziecko działa (nie mogę go zobaczyć, kiedy typ PS)

może ktoś wyjaśnić, co się dzieje

EDIT:.?

Uruchomiłem go podczas debugowania i otrzymałem:

### Rozwidla się, ale nie wiem, jak utworzyć nowe urządzenie TTY.

Ponieważ dwa debuggery walczą o tę samą TTY, wejście jest poważnie splątane.

Wiem, jak przełączać wyjście do innego okna tylko w xtermach i OS/2. W przypadku przełącznika ręcznego wpisz nazwę utworzonego TTY w $ DB :: fork_TTY lub określ funkcję DB :: get_fork_TTY() zwracającą to.

W systemach uniksowych można uzyskać nazwy TTY dla danego okna wpisując tty i odłącz powłokę z TTY przez sen 1000000.

+1

Jeśli ktoś ma rozwiązanie tego problemu poza "ekranem" (którego nie zawsze mam do dyspozycji), bardzo chciałbym to zobaczyć. – mob

Odpowiedz

8

Ilekroć uruchomieniu pracy w tle poprzez nieinterakcyjnych poleceń ssh , musisz zamknąć lub w inny sposób związać stdin, stdout, & stderr. W przeciwnym razie ssh będzie czekał na zakończenie procesu w tle. FAQ.

Nazywa się to odłączeniem lub odłączeniem od terminala sterującego i jest ogólną najlepszą praktyką podczas pisania zadań w tle, nie tylko dla SSH.

więc najprostszym zmiana, która nie wyciszyć całą polecenia jest dodanie:

#close std fds inherited from parent 
close STDIN; 
close STDOUT; 
close STDERR; 

bezpośrednio po dokonaniu print "Output started";. Jeśli proces potomny musi drukować dane wyjściowe podczas jego pracy, należy przekierować do pliku dziennika.

+0

Awesome, który działał idealnie! –

+0

+1 dla łącza FAQ – bitmask

+0

Zmarnowane godziny na debugowanie przed przeczytaniem postu. Dzięki, działa! – Shamanu4

4

ssh [email protected] 'nohup perl script.pl'

nie są w stanie aby wyjść, ponieważ nadal jest związany proces. Musisz to zrobić nohup.

+0

Wygląda na to, że nie działa. = [ –

+0

+1 Właściwa diagnoza. -1 Błędna recepta. – mob

2

To, co się dzieje, polega na tym, że ssh wykonuje polecenie "perl script.pl" jako polecenie bezpośrednio. Jeśli masz „ekran” dostępne, można zrobić:

$ ssh [email protected] 'screen -d -m perl script.pl' 

mieć to działa na jednorodzinnego ekranie, i ponownie później z ekranem -r

+0

To działa, kontrola jest zwracana. A co z uruchamianiem tego zdalnie przez ssh jest inne niż uruchamianie go lokalnie? Czy to możliwe, gdy jest lokalny? –

+1

@Razor, gdy działa zdalnie, * jest * bez powłoki - demon ssh po drugiej stronie działa i przyłącza się do skryptu. Prawdopodobnie możesz również osiągnąć to, co chcesz, uruchamiając 'bash -c" perl script.pl "' jako komendę ssh – friedo

+0

Jednak proces nadrzędny się kończy, więc czy dołączony demon nie powinien przestać działać? –

Powiązane problemy