Perl Net::SSH2 scp_put 放置文件然后挂起

发布于 2024-11-07 02:01:11 字数 1498 浏览 7 评论 0原文

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

这是我的代码片段:

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 文件吗?

谢谢大家!

I'm using Net::SSH2's scp_put method to place one file in my home directory on a Unix server from a Windows box. I am using Strawberry Perl 5.12 (portable version). I installed the libssh2 1.2.5 binaries and then Net::SSH2 from cpan.

Here's my code snippet:

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

Output (edited for anonymity):

made SSH object\n

connected to host\n

authenticated \n

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

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

It then hangs forever (>40 minutes in one test) and needs to be killed.

What's strange is that it actually does scp the file to the remote server! It only hangs after it should have completed. I couldn't find references to this curious problem elsewhere on StackOverflow or elsewhere.

Can anyone point me in the right direction to either 1) stop it from hanging, or 2) implement (as a workaround) a timer that kills this one command after a few seconds, which is enough time to scp the file?

Thanks, everyone!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深海少女心 2024-11-14 02:01:11

您可以尝试使用 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";
}

You can try using alarm() to prod your process into behaving, if you save this example as 'alarm.pl' you can see how it works:

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";
}
扎心 2024-11-14 02:01:11

使用 Net::SFTP::Foreign 与 Net:: SSH2 后端,Net::SFTP::Foreign::后端: :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 后端。

Use Net::SFTP::Foreign with the Net::SSH2 backend, 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");

If that doesn't work either, you can try using plink (from the PuTTY project) instead of the Net::SSH2 backend.

昵称有卵用 2024-11-14 02:01:11

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

I don't think it is hanging it is just REALLY SLOW. 10x slower than what it should be. The reason the file would appear to be there is that it allocates the file before it has finished transferring. This isn't really too unexpected, Perl finds new ways to disappoint and frustrate programmers on a daily basis. Sometimes I think I spend more time working around Perl's idiosyncrasies and learning 10 slightly different ways to do the same thing than doing real work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文