1

An older version of Net::SSH had #send_signal. Since that method no longer seems to be available, have tried sending "\cC" via #send_data, and also tried closing the channel, but the remote command continues running.

What's the right way to send signals to a Net::SSH::Channel now?

Brian
  • 967
  • 7
  • 12
  • Please [edit] your question to include the code that you're using to launch this remote process which you're trying to signal. – Kenster Sep 15 '18 at 22:48

2 Answers2

0

You want to use request_pty to create a pseudo-terminal. You can use that terminal to send an interrupt command.

Dylan
  • 1,335
  • 8
  • 21
  • Had tried to go down that route, but request_pty fails (success==false), and not sure how to get past the failure. – Brian Sep 14 '18 at 17:00
  • Also not certain what to do w/ the channel provided in the request_pty block as it doesn't have a #send_signal method either. – Brian Sep 14 '18 at 17:44
0

Unless you have a PTY, you can't send control characters. This can be as easy as calling request_pty.

It took me a while to figure out, mostly as my system is a bit more complicated - I have multiple SSH sessions running and another thread needs to cause all channels to terminate, so my code looks something like this:

def do_funny_things_to_server host,user
    Net::SSH.start(host, user) do |ssh|
        @connections << ssh
        ssh.open_channel do |chan|
            chan.on_data do |ch, data|
                puts data
            end
            # get a PTY with no echo back, this is mostly to hide the "^C" that
            # is otherwise output when I interrupt the channel
            chan.request_pty(modes: [ [ Net::SSH::Connection::Term::ECHO, 0] ])
            chan.exec "tail -f /some/log/file"
        end
        ssh.loop(0.1)
        @connections.delete ssh
    end
end

def cancel_all
    @connections.each do |ssh|
        ssh.channels.each do |id,chan|
            chan.send_data "\x03"
        end
    end
end

###Rant:

There's so little documentation about how to use request_pty parameters that it can be said to not exist. I had to figure out modes: by reading both the source of net-ssh and the SSH RFC and sprinkling some educated guesses about the meaning of the word "flags" in section 8 of the RFC.

Someone pointed in another relevant (though not Ruby specific) answer that there's a "signal" message that can be used to send signals over the SSH connection, but also that OpenSSH (the implementation I use for the server) does not support it. If your server supports it, you might want to try to use it like this:

channel.send_channel_request 'signal', :string, 'INT'

See "signal" channel message in the RFC and the buffer.rb source file to understand the parameters. Insert here the expected rant about complete lack of documentation of how to use send_channel_request. The above suggestion is mostly to document for myself how to use this method.

The answer linked above also mentions an SSH extension called "break" which is supposedly supported by OpenSSH, but I couldn't get it to work to interrupt a session.

Community
  • 1
  • 1
Guss
  • 30,470
  • 17
  • 104
  • 128