Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"tail -f" process will not exit after JSch connection closed

Tags:

java

ssh

jsch

I used JSch to tail a file in remote computer. But I found that after the program exit, the "tail -f" process is still there in remote computer. if I remove the "-f" param, everything is OK.

I've tried to use "sendSignal()", but it not work. it seems the function is not implemented by OpenSSH.

Here is the testing code.

public static void main(String[] args) throws Exception {
    String usr = args[0];
    String host = args[1];
    String password = args[2];
    JSch jsch = new JSch();
    Session session = jsch.getSession(usr, host);
    String pwd = password;
    session.setPassword(pwd);
    Hashtable<String, String> config = new Hashtable<String, String>();
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);
    session.connect(15000);
    session.setServerAliveInterval(15000);


    ChannelExec m_channelExec = (ChannelExec) session.openChannel("exec");
    String cmd = "tail -f /var/log/messages";
    m_channelExec.setCommand(cmd);
    InputStream m_in = m_channelExec.getInputStream();
    m_channelExec.connect();
    BufferedReader m_bufferedReader = new BufferedReader(new InputStreamReader(m_in));
    int i = 0;
    while (++i < 10) {

        if (m_bufferedReader.ready()) {
            String line = m_bufferedReader.readLine();
            System.out.println(line);
        }
        Thread.sleep(1000);
    }
    m_bufferedReader.close();
    m_channelExec.sendSignal("SIGINT");
    m_channelExec.disconnect();
    session.disconnect();
    System.out.println("exit");
}

Is there any solution to fix this problem?

like image 418
wangke1020 Avatar asked Aug 15 '15 12:08

wangke1020


1 Answers

An execCommand does not allocate a controlling tty to the channel, so tail is actually writing to a pipe. It will continue until more data is sent to it (it will get a SIGPIPE).

the simplest solution is to allocate a tty - use:

m_channelExec.setPty(true);

At the line before the m_channelExec.connect();

Which should give you the desired behavior.

like image 142
Petesh Avatar answered Oct 27 '22 01:10

Petesh