copy contents of a remote location to a local file in ruby script - ruby

I want to copy the contents of a remote location file to some local file after an ssh connection has been made.
begin
ssh = Net::SSH.start("localhost", "user")
logger.info "conn successful!"
results = conn.exec!('ruby somefile "#{arguments}"')
#code to copy the contents of a.txt in remote location to local file
#IO.copy_stream (localfile, remotefile)
rescue
logger.info "error - cannot connect to host"
end
I tried using IO.copy_stream but that doesn't work. How do I go about this?

Use Net::SCP (which requires Net::SSH) to transfer files:
Net::SCP.download!("remote.host.com", "username",
"/remote/path", "/local/path",
:password => password)
More info here: https://rubygems.org/gems/net-scp

Related

How to use Net:SSH to upload file from server1 to server2

i have 3 web server : local server 0 ; remote server1 ;remote server2
i want to run local ruby script to upload file in server1 to server2;
how to do it? just use ruby.
i have tried shell util such as expect; it worded but how to use it in ruby?
i also tried
ssh =Net::SSH.start(host,username,:password => password) do |ssh|
remote = Net::SSH.start(host,username,:password=>password)
remote.exec!("mkdir -p path")
result = ssh.exec!("scp local_path root#remote_host:remot_path")
puts result
but this way needs to add ssh_key in each remote web server
how to fix it?

How to get list of file names from a private remote ip

I am having access to ServerA and don't have access to ServerB.I want to get the list of file names from ServerB via serverA.
I am logging into ServerA using the following command and doing some functions.
Net::SSH.start(url, user, forward_agent: true) do |ssh|
ssh.exec('scp -r source dest')
end
But i want to get the list the file names from ServerB via ServerA. How can i do it ?
Eg: Dir["/path/*.txt"] or ls *.txt
OS: Linux
Language: ruby
You can use ssh to execute a remote command:
ssh username#hostname ls -l /foo/bar
If the ls command is not enough you can always use find or any other command.
EDIT
Here you have a full working script
require 'net/ssh'
Net::SSH.start('localhost', 'user', :password => "password") do |ssh|
stdout = ''
ssh.exec!("ls -l /tmp") do |channel, stream, data|
stdout << data if stream == :stdout
end
puts stdout
end
working with ruby 2.1.2p95
Also make sure you have ruby compiled with OpenSSL:
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
EDIT 2
What you need is a tunnel, for more information check the official documentation.
require 'net/ssh/gateway'
gateway = Net::SSH::Gateway.new('host', 'user')
gateway.ssh("host.private", "user") do |ssh|
puts ssh.exec!("hostname")
end
gateway.open("host.private", 80) do |port|
Net::HTTP.get_print("127.0.0.1", "/path", port)
end
gateway.shutdown!

Net::SSH does not seem to connect to remote host

Following the syntax from http://net-ssh.github.io/net-ssh/
Net::SSH.start('remotehost', 'ava') do |ssh|
puts `hostname`
end
It prints the name of current hostname rather than remote hostname. What is wrong?
You should use as below :
Net::SSH.start('remotehost', 'ava') do |ssh|
puts ssh.host
end
As ssh is an instance of Net::SSH::Connection::Session class And if you browse the documentation,you will get the method #host,which will give you the desired result.

Something is puzzling me about the use of ftp.nlst on a windows ftp server

So I was reading the documentation for the method nlst in the NET::FTP module (ruby-1.8.6). The source code displayed is
# File net/ftp.rb, line 602
def nlst(dir = nil)
cmd = "NLST"
if dir
cmd = cmd + " " + dir
end
files = []
retrlines(cmd) do |line|
files.push(line)
end
return files
end
So the command is written literally in the string cmd, executed via retrlines and the list of files is given back right?
The thing I don't understand is that on my windows ftp server there is no such command:
230 User logged in.
Remote system type is Windows_NT.
ftp> nlst
?Invalid command
ftp>
and yet the the method returns the file list. How is it possible? The source code doesn't appear to have an abstraction of some sort on the command and also the source code of retrlines doesn't have anything special (to me).
# File lib/net/ftp.rb, line 475
def retrlines(cmd) # :yield: line
synchronize do
with_binary(false) do
conn = transfercmd(cmd)
loop do
line = conn.gets
break if line == nil
yield(line.sub(/\r?\n\z/, ""), !line.match(/\n\z/).nil?)
end
conn.close
voidresp
end
end
end
I traced back the methods called to sendcmd inside transfercmd but I have no clue really.
The question is who is telling you ?Invalid command?
In this case it's the FTP client, not the server.
The client is just a front-end for commands that it implements, converting these front-end commands into proper FTP protocol command strings for the server.
What you're looking for is the nlist (not nlst) command in your client, which will issue the NLST FTP protocol command to the server.
ftp> help nlst
?Invalid help command nlst
ftp> help nlist
nlist nlist contents of remote directory
ftp>

Calling scp from net:ssh

Here's the setup:
I have server A, which is running my ruby scripts and servers B & C. I need to be able to transfer files from B to C.
I've experimented with using Net:SCP, but I haven't found a way to set up a transfer between the two remote servers. The best I've been able to do was go from B to A and then from A to C.
Based on some example code I've seen elsewhere, I'm trying to ssh onto B and call scp from that server:
Net::SSH.start(host, user, :password => pword) do |ssh|
ssh.exec! "scp /filename user#serverC:/filename" do |channel, stream, data|
channel.send_data "#{pword}\n"
end
end
This is not working for me. Is this even possible?

Resources