2011-09-07 6 views
5

Im utilizando sshj y estoy tratando de alinear un archivo, pero mi problema es que el proceso remoto nunca se mata.Asesinato de un proceso a través de sshj

En el siguiente código de ejemplo, puede ver que trato de cola/var/log/syslog, y luego envío una señal de muerte al proceso. Sin embargo, después de que la aplicación se detuvo y enumero todos los procesos en el servidor, todavía puedo ver un proceso de cola activa.

¿Por qué este código no mata el proceso? y ¿qué puedo hacer para remediar eso?

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(); 
    } 

EDITAR

también trató de enviar todas las señales disponibles.

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

¿realmente ves la línea '** exit status:' en la salida del programa? –

+0

Sí, '** estado de salida: nulo'. – netbrain

+0

¿Puedes probar con otra señal, como 'TERM '(el valor predeterminado utilizado por la utilidad kill command line)? –

Respuesta

2

Esto es muy probablemente un problema con la implementación del servidor ssh, como He intentado utilizar dos clientes ssh diferentes y obtener el mismo resultado. Mi solución terminó siendo una lógica de cola del lado del cliente, en lugar de "tail -f" para evitar los procesos de itinerancia libre.

3

OpenSSH no lo soporta https://bugzilla.mindrot.org/show_bug.cgi?id=1424

Sólo tiene que utilizar cmd.close(), que debe denominar el proceso, así

+1

en primer lugar, no estoy utilizando openssh ... y también cmd.close() no mata el proceso. Parece que el registro indica 'net.schmizz.sshj.connection.channel.AbstractChannel sendClose INFO: Enviando close' y sigue pendiente de esto hasta que se produce una excepción de tiempo de espera. – netbrain

1

Tuve un problema similar recientemente. En mi caso específico, fue el problema OpenSSH mencionado por @shikhar.

Mi solución fue ejecutar iniciar otra sesión (compartir la conexión) y ejecutar un comando de matar pgrep mycommand | xargs kill.

4

La asignación de un PTY y el envío de un código de carácter Ctrl + C hizo el truco para mí:

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(); 
} 

Por supuesto, ser capaz de enviar señales sería mejor, pero si incluso el servidor OpenSSH no lo soporta , no hay esperanza allí:/

+0

Has salvado mi vida. Muchas gracias. – Umut

+1

Estoy usando esto en combinación con [timeout de coreutil] (https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html) – TheConstructor

Cuestiones relacionadas