【问题标题】:Perl Net::SSH2 scp_put puts file and then hangsPerl Net::SSH2 scp_put 放置文件然后挂起
【发布时间】:2011-08-24 11:31:46
【问题描述】:

我正在使用 Net::SSH2 的 scp_put 方法从 Windows 机器将一个文件放在 Unix 服务器上的主目录中。我正在使用草莓 Perl 5.12(便携版)。我安装了 libssh2 1.2.5 二进制文件,然后从 cpan 安装了 Net::SSH2。

这是我的代码 sn-p:

sub uploadToHost{

my $file=@_[0];
my $host=@_[1];
my $user=@_[2];
my $pass=@_[3];
my $remotelocation=@_[4];

#makes a new SSH2 object
my $ssh=Net::SSH2->new() or die "couldn't make SSH object\n"; 

#prints proper error messages
$ssh->debug(1);

#nothing works unless I explicitly set blocking on
$ssh->blocking(1);
print "made SSH object\n";

#connect to host; this always works
$ssh->connect($host) or die "couldn't connect to host\n"; 
print "connected to host\n";

#authenticates with password
$ssh->auth_password($user, $pass) or die "couldn't authenticate $user\n";
print "authenticated $user\n";

#this is the tricky bit that hangs
$ssh->scp_put($file, $remotelocation") or die "couldn't put file in $remotelocation\n";
print "uploaded $file successfully\n";

$ssh->disconnect or die "couldn't disconnect\n";

} #ends sub

输出(为匿名编辑):

创建 SSH 对象\n

连接到主机\n

已通过身份验证\n

libssh2_scp_send_ex(ss->session, path, mode, size, mtime, atime) -> 0x377e61c\n

Net::SSH2::Channel::read(size = 1, ext = 0)\n

然后它会永远挂起(在一次测试中 > 40 分钟)并且需要被杀死。

奇怪的是它实际上确实将文件scp到远程服务器!它只是在它应该完成后挂起。我在 StackOverflow 或其他地方找不到对这个奇怪问题的引用。

谁能指出我正确的方向 1) 阻止它挂起,或 2) 实现(作为一种解决方法)一个计时器,它会在几秒钟后终止这个命令,这是足够的时间来 scp 文件?

谢谢大家!

【问题讨论】:

    标签: windows perl ssh scp


    【解决方案1】:

    您可以尝试使用 alarm() 来促使您的进程正常运行,如果将此示例保存为“alarm.pl”,您可以看到它是如何工作的:

    use strict;
    use warnings;
    use 5.10.0;
    
    # pretend to be a slow process if run as 'alarm.pl s'
    if (@ARGV && $ARGV[0] eq 's') {
        sleep(30);
        exit();
    }
    
    # Otherwise set an alarm, then run myself with 's'
    eval {
        local $SIG{ALRM} = sub {die "alarmed\n"};
        alarm(5);
        system("perl alarm.pl s");
    };
    if ($@) {
        die $@ unless $@ eq "alarmed\n";
        say "Timed out slow process";
    }
    else {
        say "Slow process finished";
    }
    

    【讨论】:

      【解决方案2】:

      Net::SFTP::Foreign 与 Net::SSH2 后端一起使用,Net::SFTP::Foreign::Backend::Net_SSH2:

      use Net::SFTP::Foreign;
      
      my $sftp = Net::SFTP::Foreign->new($host, user => $user, password => $password, backend => Net_SSH2);
      $sftp->die_on_error("Unable to connect to remote host");
      
      $sftp->put($file, $remotelocation);
      $sftp->die_on_error("Unable to copy file");
      

      如果这也不起作用,您可以尝试使用 plink(来自 PuTTY 项目)而不是 Net::SSH2 后端。

      【讨论】:

        【解决方案3】:

        我不认为它挂了它只是真的很慢。比应有的速度慢 10 倍。文件似乎存在的原因是它在完成传输之前分配了文件。这并不是太出乎意料,Perl 每天都会找到让程序员失望和沮丧的新方法。有时我想我会花更多的时间来解决 Perl 的特性,并学习 10 种与实际工作略有不同的方法来做同样的事情。

        【讨论】:

        • 只是补充一点,它看起来开始很慢,在一个可以达到 5MB/s 的链接上大约 150kB/s,但是在传输了大约 2MB 的数据后,它会减慢到大约 5KB /秒。所以它实际上比它应该运行的速度慢了 1000 倍。
        猜你喜欢
        • 1970-01-01
        • 2016-08-21
        • 1970-01-01
        • 1970-01-01
        • 2015-12-03
        • 2016-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多