Ruby Net-Ssh Login Shell

ruby net-ssh login shell

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.

Using Net::SSH to login to shell and get stateful output

Net::SSH has been updated a few days ago, and using the first example of the README on the first page of the project did exactly what you wanted to do :

require 'net/ssh'

Net::SSH.start('my_server', 'my_user') do |ssh|
output = ssh.exec!("ls")
puts output
end

#=>
# 20130402_083136_DSCF0923.jpg
# 20160715_113357_DSC_6050.jpg
# 20160715_121646_DSC_2.jpg
...
...

Interactive SSH session using Net::SSH or creating a STDIN Socket

Sockets are really nothing more than file descriptors, and since STDIN is a file descriptor too, it doesn't hurt to try.

What you want however, is to put the TTY into raw mode first to get interactivity.

This code seems to work fine:

begin
system('stty cbreak -echo')

Net::SSH.start(...) do |session|
session.open_channel do |...|
...
session.listen_to(STDIN) { |stdin|
input = stdin.readpartial(1024)
channel.send_data(input) unless input.empty?
}
end.wait
end
ensure
system('stty sane')
end

ruby net-ssh calling bash script with interactive prompts

managed to fix this by using the channel function, here's the method I use now

def connect(host,command)

require 'rubygems'
require 'net/ssh'

user = LocalConfig::SSH_DETAILS[:user]
pass = LocalConfig::SSH_DETAILS[:pass

o = ""
Net::SSH.start(host, user, :password => pass, :paranoid => false, :auth_methods => ['password'], :timeout => 30 )do |ssh |
channel = ssh.open_channel do |ch|
ch.exec(command) do |ch2, success|
ch2.send_data "myUserName\n"
ch2.send_data "mPassWord\n"

ch.on_data do |ch2, data|
o += data
end
end
end
channel.wait
return o.to_s
end
end

Ruby Net-SSH-Shell get standard out from execute! method

Have you tried doing it this way?

Net::SSH.start('host','user') do |ssh|
ssh.shell do |bash|
process = bash.execute! 'ls'
process.on_output do |a, b|
# a is the process itself, b is the output
p [a, b]
end
end
end

You can have a look at the definition of Net::SSH::Process here: https://github.com/mitchellh/net-ssh-shell/blob/master/lib/net/ssh/shell/process.rb

EDIT

I think the problem lies with the ! in execute! because the following works fine for me:

require 'net/ssh'
require 'net/ssh/shell'

Net::SSH.start('students.iitmandi.ac.in', 'k_vikhyat') do |ssh|
ssh.shell do |bash|
process = bash.execute 'whoami'
process.on_output do |a, b|
p b
end
bash.wait!
bash.execute! 'exit'
end
end

I am not sure why this is the case, because it looks like execute! creates a process, runs wait! and then returns the process.

Ruby net/ssh is not running bash commands in background

You need to redirect both stdout and stderr somewhere else than the terminal, otherwise exec! will hang waiting for process output.

This is the simplest solution I found:

ssh.exec!("sleep 600 &> /dev/null &")

&> redirects both stdin and stderr at the same time.
If you want to redirect the output for logging, you can do so separately if you like:

ssh.exec!("command 2> error.log > output.log &")

Cant run Ruby script via gem ssh-net

The problem is in your ssh.exec! call. Net::SSH does not use a login shell to run your commands. A login shell is required for Bash to execute .bash_profile.

Since your rbenv setup is in .bash_profile, your exec! call will be missing your full Ruby environment, and therefore running bundle later in you restart script will fail.

The solution should be to manually execute .bash_profile, so that rbenv gets loaded:

output = ssh.exec!("source ~/.bash_profile; ...rest of commands...")

More information and other proposals here:

net-ssh and remote environment



Related Topics



Leave a reply



Submit