6

Is there any way i can get a login shell in ruby using net-ssh? Is that even possible?

By login shell i mean the ones the source /etc/profile..

2
  • It should definitely be possible but not sure how in the API. Maybe open_channel? It's hard to tell. Commented Feb 20, 2011 at 9:00
  • doesn't work i still don't get a login shell. Actually hoped this would work though.. Commented Feb 22, 2011 at 3:36

2 Answers 2

14

Net-SSH is too low level to simply provide this up front (the way it is now, anyways). You can check out Net-SSH-Shell which builds upon Net-SSH to add login shell functionality: https://github.com/mitchellh/net-ssh-shell

The implementation is solid and works, however I found its not too useful since you can't specifically extract things like stderr or exit status because the commands run in a sub-shell, so you can only get stdout. The net-ssh-shell library uses some hacks to get the exit status.

I've needed a "login shell" for my own Ruby projects and to do this I've generally executed things directly into the shell using the following code:

def execute_in_shell!(commands, shell="bash")
  channel = session.open_channel do |ch|
    ch.exec("#{shell} -l") do |ch2, success|
      # Set the terminal type
      ch2.send_data "export TERM=vt100\n"

      # Output each command as if they were entered on the command line
      [commands].flatten.each do |command|
        ch2.send_data "#{command}\n"
      end

      # Remember to exit or we'll hang!
      ch2.send_data "exit\n"

      # Configure to listen to ch2 data so you can grab stdout
    end
  end

  # Wait for everything to complete
  channel.wait
end

With this solution you still don't get exit status or stderr of commands run into the login shell, but at least the commands are executed in that context.

I hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Good project, just a few years old, and there's a couple pull requests.
1

There is a nicer way to do this now. Instead you can use a shell subsystem with a pty to get everything you would expect from a shell login:

Net::SSH.start(@config.host, @config.user, :port => @config.port, :keys => @config.key, :config => true) do |session|
  session.open_channel do |channel|
    channel.request_pty
    channel.send_channel_request "shell" do |ch, success|
      if success
        ch.send_data "env\n"
        ch.send_data "#{command}\n"
        ch.on_data do |c, data|
          puts data
        end
      end
      channel.send_data "exit\n"

      channel.on_close do
        puts "shell closed"
      end
    end
  end
end

end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.