Code Monkey home page Code Monkey logo

net-scp's Introduction

Gem Version Join the chat at https://gitter.im/net-ssh/net-ssh Build status Coverage status Backers on Open Collective Sponsors on Open Collective

Net::SSH 7.x

As of v2.6.4, all gem releases are signed. See INSTALL.

DESCRIPTION:

Net::SSH is a pure-Ruby implementation of the SSH2 client protocol. It allows you to write programs that invoke and interact with processes on remote servers, via SSH2.

FEATURES:

  • Execute processes on remote servers and capture their output
  • Run multiple processes in parallel over a single SSH connection
  • Support for SSH subsystems
  • Forward local and remote ports via an SSH connection

Supported Algorithms

Net::SSH 6.0 disables by default the usage of weak algorithms. We strongly recommend that you install a servers's version that supports the latest algorithms.

It is possible to return to the previous behavior by adding the option : append_all_supported_algorithms: true

Unsecure algoritms will definitely be removed in Net::SSH 8.*.

Host Keys

Name Support Details
ssh-rsa OK
ssh-ed25519 OK Require the gem ed25519
ecdsa-sha2-nistp521 OK using weak elliptic curves
ecdsa-sha2-nistp384 OK using weak elliptic curves
ecdsa-sha2-nistp256 OK using weak elliptic curves
ssh-dss Deprecated in 6.0 unsecure, will be removed in 8.0

Key Exchange

Name Support Details
curve25519-sha256 OK Require the gem x25519
ecdh-sha2-nistp521 OK using weak elliptic curves
ecdh-sha2-nistp384 OK using weak elliptic curves
ecdh-sha2-nistp256 OK using weak elliptic curves
diffie-hellman-group1-sha1 Deprecated in 6.0 unsecure, will be removed in 8.0
diffie-hellman-group14-sha1 OK
diffie-hellman-group-exchange-sha1 Deprecated in 6.0 unsecure, will be removed in 8.0
diffie-hellman-group-exchange-sha256 OK

Encryption algorithms (ciphers)

Name Support Details
aes256-ctr / aes192-ctr / aes128-ctr OK
[email protected] OK. Requires the gem rbnacl
aes256-cbc / aes192-cbc / aes128-cbc Deprecated in 6.0 unsecure, will be removed in 8.0
[email protected] Deprecated in 6.0 unsecure, will be removed in 8.0
blowfish-ctr blowfish-cbc Deprecated in 6.0 unsecure, will be removed in 8.0
cast128-ctr cast128-cbc Deprecated in 6.0 unsecure, will be removed in 8.0
3des-ctr 3des-cbc Deprecated in 6.0 unsecure, will be removed in 8.0
idea-cbc Deprecated in 6.0 unsecure, will be removed in 8.0
none Deprecated in 6.0 unsecure, will be removed in 8.0

Message Authentication Code algorithms

Name Support Details
hmac-sha2-512-etm OK
hmac-sha2-256-etm OK
hmac-sha2-512 OK
hmac-sha2-256 OK
hmac-sha2-512-96 Deprecated in 6.0 removed from the specification, will be removed in 8.0
hmac-sha2-256-96 Deprecated in 6.0 removed from the specification, will be removed in 8.0
hmac-sha1 OK for backward compatibility
hmac-sha1-96 Deprecated in 6.0 unsecure, will be removed in 8.0
hmac-ripemd160 Deprecated in 6.0 unsecure, will be removed in 8.0
hmac-md5 Deprecated in 6.0 unsecure, will be removed in 8.0
hmac-md5-96 Deprecated in 6.0 unsecure, will be removed in 8.0
none Deprecated in 6.0 unsecure, will be removed in 8.0

SYNOPSIS:

In a nutshell:

require 'net/ssh'

Net::SSH.start('host', 'user', password: "password") do |ssh|

# capture all stderr and stdout output from a remote process
output = ssh.exec!("hostname")
puts output

# capture only stdout matching a particular pattern
stdout = ""
ssh.exec!("ls -l /home/jamis") do |channel, stream, data|
  stdout << data if stream == :stdout && /foo/.match(data)
end
puts stdout

# run multiple processes in parallel to completion
ssh.exec "sed ..."
ssh.exec "awk ..."
ssh.exec "rm -rf ..."
ssh.loop

# open a new channel and configure a minimal set of callbacks, then run
# the event loop until the channel finishes (closes)
channel = ssh.open_channel do |ch|
  ch.exec "/usr/local/bin/ruby /path/to/file.rb" do |ch, success|
    raise "could not execute command" unless success

    # "on_data" is called when the process writes something to stdout
    ch.on_data do |c, data|
      $stdout.print data
    end

    # "on_extended_data" is called when the process writes something to stderr
    ch.on_extended_data do |c, type, data|
      $stderr.print data
    end

    ch.on_close { puts "done!" }
  end
end

channel.wait

# forward connections on local port 1234 to port 80 of www.capify.org
ssh.forward.local(1234, "www.capify.org", 80)
ssh.loop { true }
end

See Net::SSH for more documentation, and links to further information.

REQUIREMENTS:

The only requirement you might be missing is the OpenSSL bindings for Ruby with a version greather than 1.0.1. These are built by default on most platforms, but you can verify that they're built and installed on your system by running the following command line:

ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'

If that spits out something like OpenSSL 1.0.1 14 Mar 2012, then you're set. If you get an error, then you'll need to see about rebuilding ruby with OpenSSL support, or (if your platform supports it) installing the OpenSSL bindings separately.

INSTALL:

gem install net-ssh # might need sudo privileges

NOTE: If you are running on jruby on windows you need to install jruby-pageant manually (gemspec doesn't allow for platform specific dependencies at gem installation time).

However, in order to be sure the code you're installing hasn't been tampered with, it's recommended that you verify the signature. To do this, you need to add my public key as a trusted certificate (you only need to do this once):

# Add the public key as a trusted certificate
# (You only need to do this once)
curl -O https://raw.githubusercontent.com/net-ssh/net-ssh/master/net-ssh-public_cert.pem
gem cert --add net-ssh-public_cert.pem

Then, when install the gem, do so with high security:

gem install net-ssh -P HighSecurity

If you don't add the public key, you'll see an error like "Couldn't verify data signature". If you're still having trouble let me know and I'll give you a hand.

For ed25519 public key auth support your bundle file should contain ed25519, bcrypt_pbkdf dependencies.

gem install ed25519
gem install bcrypt_pbkdf

For curve25519-sha256 kex exchange support your bundle file should contain x25519 dependency.

RUBY SUPPORT

RUNNING TESTS

If you want to run the tests or use any of the Rake tasks, you'll need Mocha and other dependencies listed in Gemfile

Run the test suite from the net-ssh directory with the following command:

bundle exec rake test

NOTE : you can run test on all ruby versions with docker :

docker-compose up --build

Run a single test file like this:

ruby -Ilib -Itest test/transport/test_server_version.rb

To run integration tests see here

BUILDING GEM

rake build

GEM SIGNING (for maintainers)

If you have the net-ssh private signing key, you will be able to create signed release builds. Make sure the private key path matches the signing_key path set in net-ssh.gemspec and tell rake to sign the gem by setting the NET_SSH_BUILDGEM_SIGNED flag:

NET_SSH_BUILDGEM_SIGNED=true rake build

For time to time, the public certificate associated to the private key needs to be renewed. You can do this with the following command:

gem cert --build [email protected] --private-key path/2/net-ssh-private_key.pem
mv gem-public_cert.pem net-ssh-public_cert.pem
gem cert --add net-ssh-public_cert.pem

or rake cert:update_public_when_expired

Security contact information

See SECURITY.md

CREDITS

Contributors

This project exists thanks to all the people who contribute.

contributors

Backers

Thank you to all our backers! ๐Ÿ™ Become a backer

backers

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. Become a sponsor

Sponsor

LICENSE:

(The MIT License)

Copyright (c) 2008 Jamis Buck

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

net-scp's People

Contributors

arthurschreiber avatar b-dean avatar bearded avatar chqr avatar delano avatar hana-da avatar jamis avatar jwils avatar kimhmadsen avatar mfazekas avatar mishina2228 avatar mjgiarlo avatar nickhammond avatar phoffer avatar robertcheramy avatar seandilda avatar stromweld avatar tas50 avatar tayjaybabee avatar terceiro avatar vinyar avatar voxik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

net-scp's Issues

File remains locked if scp returns non-zero

I'm using the upload! method to push zip archives to a remote location. After getting a SCP did not finish successfully (1): (Net::SCP::Error) I am finding that the file I tried to upload is locked.

Here is the method I am using for my Rails API application:

def copy_to_remote (local_path, remote_path, ssh)  
    session_options = {
      :password => ssh[:password],
      #:verbose => Logger::DEBUG,
      :timeout => 10
    }

    begin  
      # copy to remote location
      Net::SCP.start(ssh[:host], ssh[:user], session_options) do |scp|
        scp.upload!(local_path, remote_path)
      end

    rescue Net::SSH::AuthenticationFailed
      raise Exceptions::ArchiveAuthenticationFailed, "Could not authenticate with remote location"

    rescue Net::SSH::ConnectionTimeout
      raise Exceptions::ArchiveConnectionTimeout, "Connection timed out with remote location"

    rescue Net::SSH::Disconnect
      raise Exceptions::ArchiveDisconnect, "Lost connection with remote location"

    rescue Net::SCP::Error => e
      raise Exceptions::ArchiveCopyError, "Could not copy archive to remote location - #{e.message}"

    ensure
      # can't remove as file is locked. 
      FileUtils.rm_rf(local_path) if File::exists?(local_path)        
    end

  end

I have tried all kinds of permutations of calling upload, I have also tried manually closing the channel but I can't seem to get it to lose its grip on my file.

Need to input password on RHEL 8 while it shouldn't

Net::SCP.download!" is getting a password prompt for RHEL 8 hosts.
But if directly execute scp command to download the same file from the same host the password is not needed.
We already do below setting on the host:

  1. copied id_rsa.pub to authorized keys to avoid password prompt
  2. added config file to avoid HostKeyChecking prompt:
    Host *
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    LogLevel QUIET

Could anyone help to how to fix this issue?
We are using version v3.0.0

invalid X509 certificate

I just tried to follow installation instructions, I get this error:

gem cert --add ./gem-public_cert.pem
ERROR:  While executing gem ... (OptionParser::InvalidArgument)
    invalid argument: --add ./gem-public_cert.pem: invalid X509 certificate

# create a directory with scp

I am trying create a directory in my remote location.

Is their any command equivalent in scp as sftp.

# create a directory
sftp.mkdir! "/path/to/directory"

Hope, Get some response. Thanks!

verbose mode

I can't get the verbose mode to work.
I tried with

      ssh.scp.upload!(LOCAL_DIR, REMOTE_DIR, recursive: true, verbose: true ) if action == "give"
      ssh.scp.upload!(LOCAL_DIR, REMOTE_DIR, { recursive: true, verbose: true }) if action == "give"
      ssh.scp.upload!(LOCAL_DIR, REMOTE_DIR, recursive: true, verbose: :debug) if action == "give"
      ssh.scp.upload!(LOCAL_DIR, REMOTE_DIR, { recursive: true, verbose: :debug }) if action == "give"

but none worked and the documentation doesn't seem to show well how to get the output.

rake test fails with mocha > 2.1.0

When using mocha > 2.1.0, the rake test fails:

Error: test_upload_should_raise_error_if_gets_not_ok(TestUpload):
  NoMethodError: undefined method `sequences' for "file::stat":String
  
          expectation.in_sequence(@mockery.sequences.last) if @mockery.sequences.any?
                                                                      ^^^^^^^^^^
/home/cheramr/net-scp/vendor/bundle/ruby/3.1.0/gems/mocha-2.3.0/lib/mocha/mock.rb:157:in `block in stubs'
/home/cheramr/net-scp/vendor/bundle/ruby/3.1.0/gems/mocha-2.3.0/lib/mocha/argument_iterator.rb:10:in `block in each'
/home/cheramr/net-scp/vendor/bundle/ruby/3.1.0/gems/mocha-2.3.0/lib/mocha/argument_iterator.rb:9:in `each'
/home/cheramr/net-scp/vendor/bundle/ruby/3.1.0/gems/mocha-2.3.0/lib/mocha/argument_iterator.rb:9:in `each'
/home/cheramr/net-scp/vendor/bundle/ruby/3.1.0/gems/mocha-2.3.0/lib/mocha/mock.rb:152:in `stubs'
/home/cheramr/net-scp/test/common.rb:86:in `stub!'
/home/cheramr/net-scp/test/common.rb:47:in `prepare_file'
/home/cheramr/net-scp/test/test_upload.rb:273:in `test_upload_should_raise_error_if_gets_not_ok'
     270:   end
     271: 
     272:   def test_upload_should_raise_error_if_gets_not_ok
  => 273:     prepare_file("/path/to/local.txt", "")
     274: 
     275:     expect_scp_session "-t /path/to/remote.txt" do |channel|
     276:       channel.gets_data "\1"

freerange/mocha#645 gives the reason - Mocha::Mock.new is not supported, one have to use mock() :

This does not work as the classes FileEntry and Directory do not inherit Test::Unit::TestCase and are not monkey-patched with mocha (as far as I understand this right...)

test fails on ruby2.7

$ rake test
Mocha deprecation warning at /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:168:in `require': Require 'mocha/test_unit', 'mocha/minitest' or 'mocha/api' instead of 'mocha/setup'.
Loaded suite /home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/rake-13.0.1/lib/rake/rake_test_loader
Started
......E
==============================================================================================================================================================================
F
==============================================================================================================================================================================
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit.rb:511:in `block (2 levels) in <top (required)>'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb:66:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb:438:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb:495:in `change_work_directory'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb:439:in `block in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnerutilities.rb:24:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunner.rb:25:in `start'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunner.rb:40:in `start_mediator'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:39:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:39:in `catch'/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:41:in `block in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:102:in `with_listener'/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:45:in `block (2 levels) in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:67:in `run_suite'/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:53:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:124:in `run_test'/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:53:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:124:in `run_test'/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:53:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:124:in `run_test'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:527:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:527:in `catch'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:528:in `block in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:286:in `run_setup'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:251:in `run_fixture'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:529:in `block (2 levels) in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:535:in `rescue in block (2 levels) in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:837:in `handle_exception'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:837:in `each'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:841:in `block in handle_exception'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/error.rb:93:in `handle_all_exception'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/error.rb:121:in `add_error'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/error.rb:131:in `add_error'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testresult.rb:128:in `notify_fault'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `notify_listeners'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `each'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `block in notify_listeners'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:98:in `block in with_listener'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `notify_listeners'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `each'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `block in notify_listeners'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:101:in `add_fault'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:504:in `output_progress_in_detail'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:200:in `output_fault_in_detail'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:236:in `output_fault_backtrace'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:236:in `each_with_index'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:236:in `each'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:239:in `block in output_fault_backtrace'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:265:in `fetch_code_snippet'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/code-snippet-fetcher.rb:10:in `fetch'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/code-snippet-fetcher.rb:22:in `source'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/code-snippet-fetcher.rb:29:in `read_source'
Failure: test_download_file_with_metacharacters_in_name_should_escape_remote_file_name(TestDownload):
  unexpected invocation: File.open("/home/terceiro/src/debian/ruby-team/ruby-net-scp/test/test_download.rb", "rb") { ... }
  satisfied expectations:
  - allowed any number of times, invoked never: File.new("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt", "wb", 438)
  - allowed any number of times, invoked never: File.open("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt", "rb")
  - allowed any number of times, invoked never: File.file?("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt")
  - allowed any number of times, invoked never: File.directory?("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt")
  - allowed any number of times, invoked never: File.stat("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt")
==============================================================================================================================================================================
.................E
==============================================================================================================================================================================
F
==============================================================================================================================================================================
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit.rb:511:in `block (2 levels) in <top (required)>'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb:66:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb:438:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb:495:in `change_work_directory'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/autorunner.rb:439:in `block in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnerutilities.rb:24:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunner.rb:25:in `start'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunner.rb:40:in `start_mediator'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:39:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:39:in `catch'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:41:in `block in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:102:in `with_listener'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:45:in `block (2 levels) in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:67:in `run_suite'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:53:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:124:in `run_test'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:53:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:124:in `run_test'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:53:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testsuite.rb:124:in `run_test'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:527:in `run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:527:in `catch'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:528:in `block in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:286:in `run_setup'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:251:in `run_fixture'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:529:in `block (2 levels) in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:535:in `rescue in block (2 levels) in run'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:837:in `handle_exception'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:837:in `each'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testcase.rb:841:in `block in handle_exception'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/error.rb:93:in `handle_all_exception'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/error.rb:121:in `add_error'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/error.rb:131:in `add_error'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/testresult.rb:128:in `notify_fault'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `notify_listeners'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `each'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `block in notify_listeners'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/testrunnermediator.rb:98:in `block in with_listener'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `notify_listeners'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `each'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/util/observable.rb:78:in `block in notify_listeners'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:101:in `add_fault'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:504:in `output_progress_in_detail'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:200:in `output_fault_in_detail'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:236:in `output_fault_backtrace'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:236:in `each_with_index'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:236:in `each'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:239:in `block in output_fault_backtrace'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/ui/console/testrunner.rb:265:in `fetch_code_snippet'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/code-snippet-fetcher.rb:10:in `fetch'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/code-snippet-fetcher.rb:22:in `source'
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/test-unit-3.3.5/lib/test/unit/code-snippet-fetcher.rb:29:in `read_source'
Failure: test_upload_file_with_metacharacters_in_name_should_escape_remote_file_name(TestUpload):
  unexpected invocation: File.open("/home/terceiro/src/debian/ruby-team/ruby-net-scp/test/test_upload.rb", "rb") { ... }
  satisfied expectations:
  - allowed any number of times, invoked never: File.new("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt", "wb", 438)
  - allowed any number of times, invoked never: File.open("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt", "rb")
  - allowed any number of times, invoked never: File.file?("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt")
  - allowed any number of times, invoked never: File.directory?("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt")
  - allowed any number of times, invoked never: File.stat("/path/to/local/\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\v\f\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\e\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F.txt")
==============================================================================================================================================================================
.........
Finished in 0.25847355 seconds.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
34 tests, 64 assertions, 2 failures, 2 errors, 0 pendings, 0 omissions, 0 notifications
94.1176% passed
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
131.54 tests/s, 247.61 assertions/s
rake aborted!
Command failed with status (1)
/home/terceiro/.ruby-standalone/gems/ruby/2.7.0/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
Tasks: TOP => test
(See full trace by running task with --trace)

I'm still not sure why. I don't understand the issue yet, but by trial and error I came out with the following patch, but I'm pretty sure it's not the correct fix:

diff --git a/test/common.rb b/test/common.rb
index 1216933..de620b5 100644
--- a/test/common.rb
+++ b/test/common.rb
@@ -62,11 +62,11 @@ class Net::SCP::TestCase < Test::Unit::TestCase
     # handles newlines just fine, so we can be reasonably confident that they
     # will work in practice
     def awful_file_name
-      (((0x00..0x7f).to_a - [0x00, 0x0a, 0x2f]).map { |n| n.chr }).join + '.txt'
+      (((0x00..0x7f).to_a - [0x00, 0x0a, 0x2b, 0x2f]).map { |n| n.chr }).join + '.txt'
     end
 
     def escaped_file_name
-      "\\\001\\\002\\\003\\\004\\\005\\\006\\\a\\\b\\\t\\\v\\\f\\\r\\\016\\\017\\\020\\\021\\\022\\\023\\\024\\\025\\\026\\\027\\\030\\\031\\\032\\\e\\\034\\\035\\\036\\\037\\ \\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+,-.0123456789:\\;\\<\\=\\>\\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\[\\\\\\]\\^_\\`abcdefghijklmnopqrstuvwxyz\\{\\|\\}\\~\\\177.txt"
+      "\\\001\\\002\\\003\\\004\\\005\\\006\\\a\\\b\\\t\\\v\\\f\\\r\\\016\\\017\\\020\\\021\\\022\\\023\\\024\\\025\\\026\\\027\\\030\\\031\\\032\\\e\\\034\\\035\\\036\\\037\\ \\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*,-.0123456789:\\;\\<\\=\\>\\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\[\\\\\\]\\^_\\`abcdefghijklmnopqrstuvwxyz\\{\\|\\}\\~\\\177.txt"
     end
 
     class FileEntry

recursive issue

in the doc it is written
:recursive - the local parameter refers to a local directory, which should be uploaded to a new directory named remote on the remote server.

Wouldn't it better to copy the local dir to remote dir ?
Because now if I upload a directory local/mine to remote/test, it will upload it to remote/test/mine.
Or what I wanted to do was remote/test to be the same as local/mine because otherwise I need to make a symlink
remote/test = remote/mine and use the function with local/mine to remote to finally get remote/test to contain the file from local/mine.
Sounds confusing, hope it is clear xD

SCP servers that do not support quoting

I maintain a .NET SCP library, and I was wondering how you guys deal with SCP servers that do not support quoting paths.

I have users that want to use our library to download or upload files to MikroTik routers, but these routers do not require quoting paths (more below). However, it's not limited to to the MikroTik routers as I was just able to reproduce the problem with the SolarWinds SFTP/SCP Server.

If you'd enclose the path with single or double quotes (I'm over-simplying it here) with these SCP servers, then you end up with files that effectively have file names that are enclosed with these quotes. This also applies to escaping characters using backslashes (eg. escaping a # with a backslash gives you a file that contains the " characters).

I don't immediately see how a quoting mechanism can be applied that works for both shell and non-shell based SCP servers.

Release the final 2.x

Hey there. Any chance the final 2.0 can ship. We'd love to pull it in at Chef and we need a non-RC release.

Thanks,
Tim

Passing in a Pathname object as local for download! fails

I'm assuming the Pathname object implements the write method, so this error is mistakenly thrown. Casting the Pathname object to a string fixes the issue, but this was rather hard to debug since the error message was about using an in-memory buffer.

To reproduce,

download! "some/path", Pathname.new("/some/other/path").parent, {
  recursive: true
}

To fix,

download! "some/path", Pathname.new("/some/other/path").parent.to_s, {
  recursive: true
}

What if we automatically perform a to_s on Pathname objects to catch this?

SCP did not finish successfully (1): (Net::SCP::Error)

/Library/Ruby/Gems/2.0.0/gems/net-scp-1.2.1/lib/net/scp.rb:365:in block (3 levels) in start_command': SCP did not finish successfully (1): (Net::SCP::Error) from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/channel.rb:591:incall'
from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/channel.rb:591:in do_close' from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/session.rb:589:inchannel_close'
from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/session.rb:468:in dispatch_incoming_packets' from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/session.rb:222:inpreprocess'
from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/session.rb:206:in process' from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/session.rb:170:inblock in loop'
from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/session.rb:170:in loop' from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/session.rb:170:inloop'
from /Library/Ruby/Gems/2.0.0/gems/net-ssh-3.0.1/lib/net/ssh/connection/session.rb:119:in close' from /Library/Ruby/Gems/2.0.0/gems/net-scp-1.2.1/lib/net/scp.rb:210:inensure in start'
from /Library/Ruby/Gems/2.0.0/gems/net-scp-1.2.1/lib/net/scp.rb:210:in start' from /Library/Ruby/Gems/2.0.0/gems/net-scp-1.2.1/lib/net/scp.rb:226:inupload!'

Both source and destination paths exist and I have correct permissions, so I can't understand what is the reason...

Readme Is incorrect

When using the static functions upload/download, ssh options need to be provided under the :ssh key. This is not reflected in the readme which reads

# upload a file to a remote server
Net::SCP.upload!("remote.host.com", "username",
  "/local/path", "/remote/path",
  :password => "password")

This will return an error. And it should read

# upload a file to a remote server
Net::SCP.upload!("remote.host.com", "username",
  "/local/path", "/remote/path",
  :ssh => {:password => "password"} )

Bug: add support for net-ssh 7 (unexpected downgrade from net-scp 3 to 1.2.1)

Hello,

net-ssh has released version 7.

In the .gemspec of this gem there is this line:

spec.add_runtime_dependency(%q<net-ssh>, [">= 2.6.5", "< 7.0.0"])

Please remove that < 7.0.0 otherwise you get a disastrous downgrade of this gem:

Fetching net-ssh 7.0.1 (was 6.1.0)
Installing net-ssh 7.0.1 (was 6.1.0)
Fetching net-scp 1.2.1 (was 3.0.0)
Installing net-scp 1.2.1 (was 3.0.0)

Unable to use SCP for locations with spaces in windows

connection=Net::SSH.start('10.102.1.1', "Administrator", password: "Password", timeout: 30)
connection.scp.download!('C:/Test Folder/Package Solutions/general.log','C:/RemoteLogs')

Traceback (most recent call last):
16: from (irb):8:in rescue in irb_binding' 15: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-scp-3.0.0/lib/net/scp.rb:321:in download!'
14: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/channel.rb:272:in wait' 13: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:180:in loop'
12: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:180:in loop' 11: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:180:in block in loop'
10: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:227:in process' 9: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/event_loop.rb:28:in process'
8: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/event_loop.rb:100:in ev_preprocess' 7: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/event_loop.rb:100:in each'
6: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:248:in ev_preprocess' 5: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:548:in dispatch_incoming_packets'
4: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:685:in channel_close' 3: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/session.rb:572:in channel_closed'
2: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-ssh-6.1.0/lib/net/ssh/connection/channel.rb:611:in do_close' 1: from C:/Ruby26/lib/ruby/gems/2.6.0/gems/net-scp-3.0.0/lib/net/scp.rb:365:in block (3 levels) in start_command'
Net::SCP::Error (SCP did not finish successfully (1): )

parallel partial scp upload ?

is there an option to make scp upload parallel parts ?

for example for a 100mb file upload 3 33mb parts in parallel ... lftp seems to support that, but using it is not trivial ... (seeing 16min -> 6min upload improvement)

Unfork

This is a great project! ๐Ÿ…

To make it more obvious that this is the canonical repository, I'd suggest unforking from the original repo (removing the text "forked from โ€ฆ").

To unfork, simply contact Github support and explain that the other repo is stale/old and that you want to unfork. They'll fix it within ~1 day.

Having a non-forked repo will help signal that this is the canonical repo, which helps focusing PRs and issues to this repo.

Unable to forward remote port to the local port using this gem in window environment

I am trying to forward the remote(ec2) port to local port to watch the jobtracker in my local browser which is running on amazon ec2 cluster. But unable to forward the remote port. Please help!

Here is my code:

Net::SSH.start('ec2-23-23-4-229.compute-1.amazonaws.com' ,'hadoop' ,:keys => "mykeypair.pem",:forward_agent => true) do |ssh|
ssh.forward.remote(9033, "localhost",9101,"ec2-23-22-4-249.compute-1.amazonaws.com")
ssh.loop { !ssh.forward.active_remotes.include?([9033, "localhost"]) }
end

Vagrant up issue / Error : SCP did not finish successfully (255): (Net::SCP::Error)

Hello All,

I am facing the below mentioned issue when trying to VAGRANT UP using Git-Bash. Kindly do the needful to resolve this issue.

Operating System : Windows 10 Pro - 20H2 (19042.631)
Vagrant - 2.2.14
Oracle Virtualbox - Version 6.1.14 r140239

Thanks in advance.

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'vagdebianbox'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: buildtest_default_1611297810775_76100
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
==> default: Attempting graceful shutdown of VM...
==> default: Destroying VM and associated drives...
C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-scp-1.2.1/lib/net/scp.rb:365:in `block (3 levels) in start_command': SCP did not finish successfully (255):  (Net::SCP::Error)
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/channel.rb:611:in `do_close'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/session.rb:572:in `channel_closed'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/session.rb:685:in `channel_close'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/session.rb:548:in `dispatch_incoming_packets'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/session.rb:248:in `ev_preprocess'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/event_loop.rb:100:in `each'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/event_loop.rb:100:in `ev_preprocess'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/event_loop.rb:28:in `process'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/session.rb:227:in `process'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/session.rb:180:in `block in loop'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/session.rb:180:in `loop'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/session.rb:180:in `loop'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-ssh-6.2.0.rc1/lib/net/ssh/connection/channel.rb:272:in `wait'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/net-scp-1.2.1/lib/net/scp.rb:284:in `upload!'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:332:in `block (2 levels) in upload'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:338:in `block in upload'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:748:in `block in scp_connect'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:392:in `connect'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:746:in `scp_connect'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:307:in `upload'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/guests/linux/cap/public_key.rb:19:in `block in insert_public_key'
        from C:/HashiCorp/Vagrant/embedded/mingw64/lib/ruby/2.6.0/tempfile.rb:295:in `open'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/guests/linux/cap/public_key.rb:14:in `insert_public_key'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/lib/vagrant/capability_host.rb:111:in `call'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/lib/vagrant/capability_host.rb:111:in `capability'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/lib/vagrant/guest.rb:43:in `capability'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:192:in `ready?'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:88:in `block in wait_for_ready'
        from C:/HashiCorp/Vagrant/embedded/mingw64/lib/ruby/2.6.0/timeout.rb:93:in `block in timeout'
        from C:/HashiCorp/Vagrant/embedded/mingw64/lib/ruby/2.6.0/timeout.rb:33:in `block in catch'
        from C:/HashiCorp/Vagrant/embedded/mingw64/lib/ruby/2.6.0/timeout.rb:33:in `catch'
        from C:/HashiCorp/Vagrant/embedded/mingw64/lib/ruby/2.6.0/timeout.rb:33:in `catch'
        from C:/HashiCorp/Vagrant/embedded/mingw64/lib/ruby/2.6.0/timeout.rb:108:in `timeout'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/plugins/communicators/ssh/communicator.rb:63:in `wait_for_ready'
        from C:/HashiCorp/Vagrant/embedded/gems/2.2.14/gems/vagrant-2.2.14/lib/vagrant/action/builtin/wait_for_communicator.rb:16:in `block in call'

I can't transfer multiple files at the same time

I would like to copy multiple files with scp. With current implementation I have to call scp for each file. I can copy whole directory but I wish to copy only some files.

So instead of this:

Net::SCP.upload!("remote.host.com", "username",
  "/local/path/file1.rb", "/remote/path/",
  :ssh => { :password => "password" })

Net::SCP.upload!("remote.host.com", "username",
  "/local/path/file2.rb", "/remote/path/",
  :ssh => { :password => "password" })

I would like to use this:

Net::SCP.upload!("remote.host.com", "username",
  "/local/path/file*.rb", "/remote/path/",
  :ssh => { :password => "password" })

Adding support for home directory relative paths

2.0.0p195 :004 > Net::SCP.upload!('server', 'deploy', 'foo.txt', '~/foo.txt')
Net::SCP::Error: SCP did not finish successfully (1)
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-scp-1.1.2/lib/net/scp.rb:359:in `block (3 levels) in start_command'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/channel.rb:591:in `call'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/channel.rb:591:in `do_close'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:586:in `channel_close'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:465:in `dispatch_incoming_packets'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:221:in `preprocess'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:205:in `process'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:169:in `block in loop'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:169:in `loop'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:169:in `loop'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:118:in `close'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-scp-1.1.2/lib/net/scp.rb:205:in `ensure in start'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-scp-1.1.2/lib/net/scp.rb:205:in `start'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/net-scp-1.1.2/lib/net/scp.rb:221:in `upload!'
    from (irb):4
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/railties-3.2.14/lib/rails/commands/console.rb:47:in `start'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/railties-3.2.14/lib/rails/commands/console.rb:8:in `start'
    from /Users/betelgeuse/.rvm/gems/ruby-2.0.0-p195/gems/railties-3.2.14/lib/rails/commands.rb:41:in `<top (required)>'
    from ./script/rails:25:in `require'
    from ./script/rails:25:in

Documenting here in case someone else stumbles on this. This prevents using home directory type urls in capistrano remote files. If someone has pointers what I should look at for creating a pull request, I could get one together.

Net::SCP seems to be failing on files roughly 10mb in size

I have a case where Net::SCP is reproducibly failing on files that are larger that 10mb. I have verified that using a command line SCP on a *nix box doesn't fail for the same file.

$ my_ruby_scp_download_program
Please wait. Generating download files...
Downloading files.
Progress: 9486336/14710663 - 64%
Progress: 9519104/14710663 - 64%
/home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:305:in `[]=': can't add a new key into hash during iteration (RuntimeError)
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:305:in `open_channel'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:329:in `exec'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:363:in `exec!'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/jump_scripts-1.5.25/lib/jump_scripts/my_session.rb:67:in `keep_alive'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/jump_scripts-1.5.25/lib/jump_scripts/grabber.rb:117:in `block in myscript'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-scp-1.1.2/lib/net/scp.rb:407:in `call'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-scp-1.1.2/lib/net/scp.rb:407:in `progress_callback'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-scp-1.1.2/lib/net/scp/download.rb:63:in `read_data_state'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-scp-1.1.2/lib/net/scp.rb:363:in `block (3 levels) in start_command'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/channel.rb:311:in `call'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/channel.rb:311:in `process'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:222:in `block in preprocess'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:222:in `each'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:222:in `preprocess'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:205:in `process'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:169:in `block in loop'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:169:in `loop'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:169:in `loop'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/channel.rb:269:in `wait'
    from /home/eng-sa/.rvm/gems/ruby-1.9.3-p484@engsa/gems/net-ssh-2.7.0/lib/net/ssh/connection/session.rb:364:in `exec!'

Here you can see regular scp on the same file works:

$ scp username@ipaddress:/tmp/download.tgz manual_download.tgz
username@ipaddress's password: 
download.tgz                                         100%   14MB  67.5KB/s   03:33  

Broken Pipe on files larger than 4GB

I have the following problem:

I try to dowload large files (20GB, 200GB) with net-scp and exactly after 4GB I get this error:

/home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/buffered_io.rb:102:in `send': Broken pipe - send(2) (Errno::EPIPE)
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/buffered_io.rb:102:in `send_pending'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/session.rb:280:in `block in ev_do_handle_events'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/session.rb:279:in `each'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/session.rb:279:in `ev_do_handle_events'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/event_loop.rb:110:in `ev_select_and_postprocess'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/event_loop.rb:29:in `process'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/session.rb:225:in `process'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/session.rb:178:in `block in loop'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/session.rb:178:in `loop'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/session.rb:178:in `loop'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-ssh-4.2.0/lib/net/ssh/connection/session.rb:124:in `close'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-scp-1.2.1/lib/net/scp.rb:210:in `ensure in start'
	from /home/marbury/.rvm/gems/ruby-2.4.3@ovirt-migration/gems/net-scp-1.2.1/lib/net/scp.rb:210:in `start'
	from /home/marbury/Projects/Work/TNG/ovirt-migration/bin/migration:89:in `run'
	from /home/marbury/Projects/Work/TNG/ovirt-migration/bin/migration:151:in `<top (required)>'
	from -e:1:in `load'
	from -e:1:in `<main>'

I can scp the file through the OpenSSH scp command just fine. So ulimit, file-system(128bit), quotas, server/client-config, and the like are not the issue. My OS and Ruby are 64bit as well (checked ruby with the unix file command).

Are there any limitations in this implementation that I don't know about? Is there a flag that can be set?

Thanks for your help,
Stefan

tests fail on ruby2.3

ruby23 -Ilib:test test/test_all.rb
Loaded suite test/test_all
Started
..E
========================================================================================================================================================================
/home/oznt/Software/net-scp/test/test_download.rb:214:in `test_download_directory_should_create_directory_and_files_locally'
F
========================================================================================================================================================================
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit.rb:502:in `block (2 levels) in <top (required)>'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/autorunner.rb:62:in `run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/autorunner.rb:434:in `run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/autorunner.rb:491:in `change_work_directory'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/autorunner.rb:435:in `block in run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunnerutilities.rb:24:in `run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunner.rb:25:in `start'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunner.rb:40:in `start_mediator'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunnermediator.rb:39:in `run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunnermediator.rb:39:in `catch'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunnermediator.rb:41:in `block in run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunnermediator.rb:102:in `with_listener'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunnermediator.rb:45:in `block (2 levels) in run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunnermediator.rb:67:in `run_suite'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testsuite.rb:53:in `run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testsuite.rb:124:in `run_test'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testsuite.rb:53:in `run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testsuite.rb:124:in `run_test'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testsuite.rb:53:in `run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testsuite.rb:124:in `run_test'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testcase.rb:496:in `run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testcase.rb:496:in `catch'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testcase.rb:497:in `block in run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/fixture.rb:286:in `run_setup'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/fixture.rb:251:in `run_fixture'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/fixture.rb:270:in `block in create_fixtures_runner'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testcase.rb:498:in `block (2 levels) in run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testcase.rb:504:in `rescue in block (2 levels) in run'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testcase.rb:798:in `handle_exception'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testcase.rb:798:in `each'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testcase.rb:802:in `block in handle_exception'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/error.rb:93:in `handle_all_exception'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/error.rb:121:in `add_error'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/error.rb:131:in `add_error'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/testresult.rb:128:in `notify_fault'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/util/observable.rb:78:in `notify_listeners'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/util/observable.rb:78:in `each'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/util/observable.rb:78:in `block in notify_listeners'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/testrunnermediator.rb:98:in `block in with_listener'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/util/observable.rb:78:in `notify_listeners'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/util/observable.rb:78:in `each'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/util/observable.rb:78:in `block in notify_listeners'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/console/testrunner.rb:101:in `add_fault'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/console/testrunner.rb:485:in `output_progress_in_detail'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/console/testrunner.rb:200:in `output_fault_in_detail'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/console/testrunner.rb:235:in `output_fault_backtrace'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/console/testrunner.rb:235:in `each_with_index'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/console/testrunner.rb:235:in `each'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/console/testrunner.rb:240:in `block in output_fault_backtrace'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/ui/console/testrunner.rb:246:in `output_code_snippet'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/code-snippet-fetcher.rb:10:in `fetch'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/code-snippet-fetcher.rb:22:in `source'
/usr/lib64/ruby/gems/2.3.0/gems/test-unit-3.2.7/lib/test/unit/code-snippet-fetcher.rb:29:in `read_source'
Failure: test_download_directory_should_create_directory_and_files_locally(TestDownload):
  unexpected invocation: File.open("/home/oznt/Software/net-scp/test/test_download.rb")
  satisfied expectations:
  - allowed any number of times, not yet invoked: Dir.entries("/path/to/local/remote/sub")
  - allowed any number of times, not yet invoked: Dir.mkdir()
  - allowed any number of times, not yet invoked: Dir.entries("/path/to/local/remote")
  - allowed any number of times, not yet invoked: Dir.mkdir()
  - allowed any number of times, not yet invoked: Dir.entries("/path/to/local")
  - allowed any number of times, not yet invoked: Dir.mkdir()
  - allowed any number of times, not yet invoked: File.new("/path/to/local/remote/sub/remote.txt", "wb", 438)
  - allowed any number of times, not yet invoked: File.open("/path/to/local/remote/sub/remote.txt", "rb")
  - allowed any number of times, not yet invoked: File.file?("/path/to/local/remote/sub/remote.txt")
  - allowed any number of times, not yet invoked: File.directory?("/path/to/local/remote/sub/remote.txt")
  - allowed any number of times, not yet invoked: File.stat("/path/to/local/remote/sub/remote.txt")
  - allowed any number of times, not yet invoked: File.file?("/path/to/local/remote/sub")
  - allowed any number of times, not yet invoked: File.directory?("/path/to/local/remote/sub")
  - allowed any number of times, not yet invoked: File.stat("/path/to/local/remote/sub")
  - allowed any number of times, not yet invoked: File.file?("/path/to/local/remote")
  - allowed any number of times, not yet invoked: File.directory?("/path/to/local/remote")
  - allowed any number of times, not yet invoked: File.stat("/path/to/local/remote")
  - allowed any number of times, not yet invoked: File.file?("/path/to/local")
  - allowed any number of times, not yet invoked: File.directory?("/path/to/local")
  - allowed any number of times, not yet invoked: File.stat("/path/to/local")
========================================================================================================================================================================
F
========================================================================================================================================================================
/home/oznt/Software/net-scp/test/test_download.rb:188:in `test_download_directory_should_raise_error_if_local_exists_and_is_not_directory'
     185:       channel.sends_ok
     186:     end
     187: 
  => 188:     e = assert_raises(Net::SCP::Error) { scp.download!("/path/to/remote", "/path/to/local", :recursive => true) }
     189:     assert_match(/exists and is not a directory/, e.message)
     190:   end
     191: 

<Net::SCP::Error> expected but was
<TypeError(<no implicit conversion of Net::SSH::Test::Socket into IO>)>

diff:
?                                      Net::SCP::Err    or             
? TypeError(<no implicit conversion of       SH  Test::S cket into IO>)
Failure: test_download_directory_should_raise_error_if_local_exists_and_is_not_directory(TestDownload)
========================================================================================================================================================================
F
========================================================================================================================================================================
/home/oznt/Software/net-scp/test/test_download.rb:158:in `test_download_directory_without_recursive_should_raise_error'
     155:       channel.gets_data "D0755 0 remote\n"
     156:     end
     157: 
  => 158:     assert_raises(Net::SCP::Error) { scp.download!("/path/to/remote") }
     159:   end
     160: 
     161:   def test_download_should_raise_error_if_gets_not_ok

<Net::SCP::Error> expected but was
<TypeError(<no implicit conversion of Net::SSH::Test::Socket into IO>)>

diff:
?                                      Net::SCP::Err    or             
? TypeError(<no implicit conversion of       SH  Test::S cket into IO>)
Failure: test_download_directory_without_recursive_should_raise_error(TestDownload)
========================================================================================================================================================================
.....F
========================================================================================================================================================================
/home/oznt/Software/net-scp/test/test_download.rb:119:in `test_download_io_with_recursive_should_raise_error'
     116: 
     117:   def test_download_io_with_recursive_should_raise_error
     118:     expect_scp_session "-f -r /path/to/remote.txt"
  => 119:     assert_raises(Net::SCP::Error) { scp.download!("/path/to/remote.txt", StringIO.new, :recursive => true) }
     120:   end
     121: 
     122:   def test_download_io_with_preserve_should_ignore_preserve

<Net::SCP::Error> expected but was
<TypeError(<no implicit conversion of Net::SSH::Test::Socket into IO>)>

diff:
?                                      Net::SCP::Err    or             
? TypeError(<no implicit conversion of       SH  Test::S cket into IO>)
Failure: test_download_io_with_recursive_should_raise_error(TestDownload)
========================================================================================================================================================================
F
========================================================================================================================================================================
/home/oznt/Software/net-scp/test/test_download.rb:171:in `test_download_should_raise_error_if_gets_not_ok'
     168:       channel.gets_data "\1"
     169:     end
     170: 
  => 171:     e = assert_raises(Net::SCP::Error) { scp.download!("/path/to/remote.txt", "/path/to/local.txt") }
     172:     assert_equal("\1", e.message)
     173:   end
     174: 

<Net::SCP::Error> expected but was
<TypeError(<no implicit conversion of Net::SSH::Test::Socket into IO>)>

diff:
?                                      Net::SCP::Err    or             
? TypeError(<no implicit conversion of       SH  Test::S cket into IO>)
Failure: test_download_should_raise_error_if_gets_not_ok(TestDownload)
========================================================================================================================================================================
F
========================================================================================================================================================================
/home/oznt/Software/net-scp/test/test_download.rb:73:in `test_download_with_error_should_respond_with_error_text'
     70:     end
     71: 
     72:     error = nil
  => 73:     assert_scripted do
     74:       begin
     75:         scp.download!("/path/to/remote.txt")
     76:       rescue
/usr/lib64/ruby/gems/2.3.0/gems/net-ssh-4.2.0/lib/net/ssh/test.rb:88:in `assert_scripted'
Failure: test_download_with_error_should_respond_with_error_text(TestDownload):
  there should not be any remaining scripted events, but there are still 1 pending.
  <false> is not true.
========================================================================================================================================================================
........F
========================================================================================================================================================================
/home/oznt/Software/net-scp/test/test_upload.rb:159:in `test_upload_directory_without_recursive_should_error'
     156:       channel.gets_ok
     157:     end
     158: 
  => 159:     assert_raises(Net::SCP::Error) { scp.upload!("/path/to/local", "/path/to/remote") }
     160:   end
     161: 
     162:   def test_upload_empty_directory_should_create_directory_and_finish

<Net::SCP::Error> expected but was
<TypeError(<no implicit conversion of Net::SSH::Test::Socket into IO>)>

diff:
?                                      Net::SCP::Err    or             
? TypeError(<no implicit conversion of       SH  Test::S cket into IO>)
Failure: test_upload_directory_without_recursive_should_error(TestUpload)
========================================================================================================================================================================
...........F
========================================================================================================================================================================
/home/oznt/Software/net-scp/test/test_upload.rb:277:in `test_upload_should_raise_error_if_gets_not_ok'
     274:       channel.gets_data "\1"
     275:     end
     276: 
  => 277:     e = assert_raises(Net::SCP::Error) { scp.upload!("/path/to/local.txt", "/path/to/remote.txt") }
     278:     assert_equal("\1", e.message)
     279:   end
     280: end

<Net::SCP::Error> expected but was
<TypeError(<no implicit conversion of Net::SSH::Test::Socket into IO>)>

diff:
?                                      Net::SCP::Err    or             
? TypeError(<no implicit conversion of       SH  Test::S cket into IO>)
Failure: test_upload_should_raise_error_if_gets_not_ok(TestUpload)
========================================================================================================================================================================

Finished in 0.294052809 seconds.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
34 tests, 61 assertions, 8 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications
76.4706% passed
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
115.63 tests/s, 207.45 assertions/s

Net::Scp raises previous command error

Hello,

I have a strange behavior with net/scp. I'm using ruby 2.3.0, ssh 3.0.2, scp 1.2.1
When a command fails, the error is "stored" and reraised on valid commands.

Here is a sample script:

require "fileutils"
require "net/scp"

# remote_ip= TODO
# remote_user= TODO

connection= Net::SSH.start(remote_ip, remote_user, :keys_only => true)
scp= Net::SCP.new(connection)

# This raises "Errno::ENOENT: No such file or directory - /tmp/no_such_file"
begin
  scp.upload!("/tmp/no_such_file", "/tmp/test")
rescue => e
  puts "#{e.class}: #{e.message}"
end

FileUtils.touch("/tmp/scp_bug_file")
scp.upload!("/tmp/scp_bug_file", "/tmp/test")

I got the following error:

Errno::ENOENT: No such file or directory @ rb_file_s_stat - /tmp/no_such_file
.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-scp-1.2.1/lib/net/scp/upload.rb:117:in `stat': No such file or directory @ rb_file_s_stat - /tmp/no_such_file (Errno::ENOENT)
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-scp-1.2.1/lib/net/scp/upload.rb:117:in `set_current'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-scp-1.2.1/lib/net/scp/upload.rb:24:in `upload_start_state'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-scp-1.2.1/lib/net/scp.rb:369:in `block (3 levels) in start_command'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/channel.rb:324:in `process'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/session.rb:223:in `block in preprocess'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/session.rb:223:in `each'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/session.rb:223:in `preprocess'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/session.rb:206:in `process'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/session.rb:170:in `block in loop'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/session.rb:170:in `loop'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/session.rb:170:in `loop'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-3.0.2/lib/net/ssh/connection/channel.rb:269:in `wait'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-scp-1.2.1/lib/net/scp.rb:284:in `upload!'
    from ./test.rb:20:in `<main>'

see: net-ssh/net-ssh#53

Downgrade of net-scp after bundle update

Hi folks,

last time we did bundle update it downgraded net-scp

  • net-ssh: 5.2.2 (2019) -> 6.0.0 (April 20, 2020)
  • net-scp: 2.0.0 (2019) -> 1.2.1 (2014)

We do not require thes gems but use capistrano which uses net-scp and net-ssh.

To fix this we had to require gem 'net-scp', '~> 2.0' directly.

Is there another way to do it or would it be possible to release Version 3 for net-scp?

Thank you in advance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.