2011-09-07 10 views
5

Im przy użyciu sshj i im próbuje ogłosić plik, ale moim problemem jest to, że zdalny proces nigdy nie jest zabity.Zabijanie procesu poprzez sshj

W poniższym przykładzie widać, że próbuję zmienić/var/log/syslog, a następnie wysyłam sygnał kill do procesu. Jednak po zatrzymaniu aplikacji i wyświetleniu listy wszystkich procesów na serwerze nadal widzę aktywny proces końcowy.

Dlaczego ten kod nie zabija procesu? i co mogę zrobić, aby temu zaradzić?

SSHClient ssh = new SSHClient(); 
    ssh.addHostKeyVerifier(new PromiscuousVerifier()); 
    try {   
     ssh.connect("localhost"); 
     ssh.authPassword("xxx", "xxx"); 
     final Session session = ssh.startSession(); 
     try { 
      final Command cmd = session.exec("tail -f /var/log/syslog"); 
      cmd.signal(Signal.KILL); 
      System.out.println("\n** exit status: " + cmd.getExitStatus()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     }finally{ 
      session.close(); 
     } 
    } finally{ 
     ssh.disconnect(); 
    } 

EDIT

próbował również wysyłając wszystkie dostępne sygnały.

  for(Signal s : Signal.values()){ 
       cmd.signal(s); 
      } 
+0

Czy rzeczywiście widzisz linię '** status wyjścia:' w wynikach programu? –

+0

Tak, '** status wyjścia: null'. – netbrain

+0

możesz spróbować z innym sygnałem, np. 'TERM' (domyślnie używanym przez narzędzie wiersza poleceń kill)? –

Odpowiedz

2

Jest to najprawdopodobniej problem z implementacji serwera ssh, jak Próbowałem użyć dwóch różnych klientów ssh i uzyskać ten sam wynik. Moje rozwiązanie okazało się być logiką ogonową po stronie klienta, zamiast "tail -f", aby zapobiec procesom darmowego roamingu.

3

OpenSSH nie obsługuje on https://bugzilla.mindrot.org/show_bug.cgi?id=1424

Wystarczy użyć cmd.close(), które powinny nazwać ten proces, jak również

+1

po pierwsze, nie używam openssh ... a także cmd.close() nie zabija procesu. Wygląda na to, że w logu znajduje się informacja: net.schmizz.sshj.connection.channel.AbstractChannel sendClose INFO: Wysyłaj close' i wciąż na tym zawieszaj dopóki nie pojawi się wyjątek timeout. – netbrain

1

Niedawno miał podobny problem. W moim konkretnym przypadku był to problem OpenSSH wspomniany przez @shikhar.

Moim rozwiązaniem było uruchomienie innej sesji (udostępnianie połączenia) i uruchomienie komendy kill pgrep mycommand | xargs kill.

4

Przypisywanie PTY i wysyłając kod znaku Ctrl + C nie trick dla mnie:

final Session session = ssh.startSession(); 
session.allocateDefaultPTY(); 
try { 
    final Command cmd = session.exec("tail -f /var/log/syslog"); 

    // Send Ctrl+C (character code is 0x03): 
    cmd.getOutputStream().write(3); 
    cmd.getOutputStream().flush(); 

    // Wait some time for the process to exit: 
    cmd.join(1, TimeUnit.SECONDS); 

    // If no exception has been raised yet, then the process has exited 
    // (but the exit status can still be null if the process has been killed). 
    System.out.println("\n** exit status: " + cmd.getExitStatus()); 
} catch (IOException e) { 
    e.printStackTrace(); 
}finally{ 
    session.close(); 
} 

Oczywiście, będąc w stanie wysyłać sygnały byłoby lepiej, ale jeśli nawet serwer OpenSSH nie obsługuje , tam nie ma nadziei:/

+0

Uratowałeś mi życie. Dziękuję bardzo. – Umut

+1

Używam tego w połączeniu z [limit czasu coreutila] (https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html) – TheConstructor

Powiązane problemy