rake with net/ssh = problems?

S

samuel_x_winters_x

The net/ssh code below works fine in irb, but dies when inside a rake
task.

task :publish do
require 'net/ssh'
Net::SSH.start('svr.com','usr','pwd') do |session|
shell = session.shell.sync
out = shell.pwd
puts out.stdout
end
end

[C:\dir]rake --rakefile ssh.rb publish
(in C:/dir)
rake aborted!
undefined method `stdout' for "C:/dir":String
C:/dir/ssh.rb:8

This is bizarre. When stepping through without rake in IRB it works
fine, and "out" is a Net::SSH struct:
irb(main):008:0> out
=> #<struct Net::SSH::Service::Shell::SyncShell::CommandOutput
stdout="/some_path_here\n", stderr=nil, status=0>

Any idea what is going on?
 
J

Joel VanderWerf

The net/ssh code below works fine in irb, but dies when inside a rake
task.

task :publish do
require 'net/ssh'
Net::SSH.start('svr.com','usr','pwd') do |session|
shell = session.shell.sync
out = shell.pwd
puts out.stdout
end
end

How does this work in irb? What does "out.stdout" do?

Maybe you meant "$stdout.puts out" ?
 
S

samuel_x_winters_x

shell = session.shell.sync

session.shell.sync gives a shell whose shell commands appear block and
synchronize when command completes.

out = shell.pwd

out is a (net/ssh) struct, and stdout is a string member. From my irb
session:

irb(main):002:0> require 'net/ssh'
=> true

irb(main):003:0> s = Net::SSH.start('svr.com','usr','pwd')
=> #<Net::SSH::Session:0x7ebb040 @host="svr.com", ........

shell = s.shell.sync
=> #<Net::SSH::Service::Shell::SyncShell:0x80552a8 .....

out = shell.pwd
=> #<struct Net::SSH::Service::Shell::SyncShell::CommandOutput
stdout="/a/directory/location\n", stderr=nil, status=0>

irb(main):006:0> puts out.stdout
/a/directory/location\n
=> nil

But in the rake task version 'out' is a string showing my current local
directory!
 
J

Jim Weirich

The net/ssh code below works fine in irb, but dies when inside a rake
task. [... example elided ...]
Any idea what is going on?

There is an unintended interaction between the FileUtils methods (which rake
defines at top level for convenience) and the use of method_missing in the
SSH SyncShell.

Rake includes the FileUtils methods (e.g. cp, rm_r, install) at the top level
of the script so that file based actions are easy to write. The SSH
SyncShell object uses method_missing to turn ruby method calls into SSH
commands sent with the send_command method. Since "pwd" is available at the
top level, shell.pwd calls that instead of invoking the method_missing
handler.

The quick workaround is to use send_command directly. The example would look
like this:

task :publish do
  require 'net/ssh'
  Net::SSH.start('svr.com','usr','pwd') do |session|
    shell = session.shell.sync
    out = shell.send_command("pwd")
    puts out.stdout
  end
end

Another workaround would be to mark the "pwd" command as private at the top
level. This allows the method_missing handler to do its thing without
interfering with the use of 'pwd' at the top level. Future versions of Rake
will do this automatically for you. But for now you can add the line

private :pwd

Somewhere in your rakefile.

Does this help?
 
S

samuel_x_winters_x

Given the size of FileUtils, seems like such a top-level inclusion (is
the whole module directly included?) could cause numerous unexpected
conflicts e.g. I'd like to use zip, zlib, and who knows what else that
might have file-like commands, and would rather not be surprised by the
way some of those commands might be _implemented_.

I'll try one of your work-arounds for now.

Thanks for the quick response.

Sam
 
J

Jim Weirich

Given the size of FileUtils, seems like such a top-level inclusion (is
the whole module directly included?) could cause numerous unexpected
conflicts

True. Its definitely a tradeoff. In the 2 years that rake has been around
this hasn't seemed to be a major issue. The next version of Rake will make
them private by default to further reduce the possibility of conflict.

If you want to try a beta version (0.5.0.1) of Rake with private FileUtils
methods, you can do this:

gem update rake --source http://onestepback.org/betagems
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top