Perl从Windows到Linux的scp文件

问题描述:

这个Perl脚本在Windows上运行,我试图从本地机器到Linux机器上scp文件,它不打印任何错误,但不复制文件。Perl从Windows到Linux的scp文件

use Net::SCP qw(scp); 
$source = 'c:\temp\a.txt'; 
$destination = '/tmp'; 
$scp = Net::SCP->new("$ip", "$user") or die "cannot scp $!"; 
print "scp $source $destination"; 
$scp->scp($source, $destination); 
+1

'$ scp-> scp(...)'的返回值是什么? '$ scp - > {errstr}'的价值是什么? – mob

Net::SCP documentation有如何调用scp()两个例子:

use Net::SCP qw(scp iscp); 
scp($source, $destination); 

$scp = new Net::SCP; 
$scp->scp($source, $destination); 

你会注意到,无论是版本显示如何指定主机名,用户名或密码,或复制操作是本地到远程或remote-to-local。

事实是,Net :: SCP文档不能很好地描述如何使用scp()。望着source code for the module表明:

  1. scp()子程序不使用任何传送到的Net :: SCP的构造函数的值。
  2. scp()调用scp命令行实用工具,将源和目标参数传递给该程序逐字

因此,指定主机名,用户名,密码和复制方向的正确方法与the scp command line utility相同。您的$source$destination值必须遵循scp程序接受的一般形式。假设你正在试图做一个本地到远程传输,你应该尝试这样的事:

$source = 'c:\temp\a.txt'; 
$destination = "${user}\@${ip}:/tmp"; 
$scp = new Net::SCP; 
$scp->scp($source, $destination); 

这将产生一个目的与形式的“[email protected]:/ tmp目录”,这是scp程序接受的表单。

如果您尝试执行远程到本地副本,则应将$ {user} \ @ $ {ip}:“字符串预置为$ source而不是$ destination。请注意,“@”前面有一个反斜杠,因为它在双引号字符串中是特殊的。另外,如果用两个本地路径名调用scp程序,它会调用系统的文件复制实用程序来执行本地复制操作。所以你可能已经将源文件名复制到C:\ tmp或本地系统上的类似位置。

+0

谢谢Kenster,错误是'scp'不被识别为内部或外部命令',我应该在本地PC上安装scp程序吗? – rodee

+0

是的,您需要在命令路径中安装并提供“scp”命令行实用程序的副本。 – Kenster

$scp = Net::SCP->new("$ip", "$user") or die "cannot scp $!"; 
$scp = new Net::SCP; 

调用Net::SCP构造的两倍。第二次,它不使用主机名或用户标识来调用它,不检查返回值,并覆盖以前正确的调用。删除这些行中的第二行。

+0

它没有帮助,无论如何。 – rodee

+0

确实如此,它只是没有足够的帮助,以显而易见:-) – mob

+0

更新我的问题中的脚本,以删除额外的构造函数。 – rodee

您正在测试成功调用scp对象的构造函数,但是您未在实际执行scp操作时测试成功。

这条线可以改进:

$scp->scp($source, $destination); 

该模块的文档指出scp失败时返回假,并设置errstr属性。所以,你可以改变该行如下:

$scp->scp($source, $destination) or die 'scp failed: ', $scp->{errstr}; 

通过这样做,你应该得到有用的诊断信息,这是真的知道了发生在解决这个问题的唯一途径。

此外,与您的问题无关,但值得一提:use Net::SCP qw(scp);是错误的,因为它将scp函数导入到您的调用名称空间中。这是错误的原因是您正在使用scp(也就是$scp->scp(...))的面向对象的“方法调用”调用。调用scp的方法调用方法不需要将任何内容导入到您的调用名称空间中。

+0

是的,愚蠢的我,谢谢,这有助于识别问题,我现在打印错误信息'scp失败:'scp'不被识别为内部或外部命令',正如kenster提到的,它试图调用本地scp命令,我认为它会使用Perl的,我不需要在我的本地PC上安装scp。 – rodee

+0

看到错误信息几乎总是进步。 :) – DavidO