Perl scp 从 windows 到 Linux 的文件
Perl scp a file from windows to Linux
Windows 上的这个 Perl 脚本 运行,我正在尝试将文件从本地机器 scp 到 Linux 机器,它没有打印任何错误,但复制文件。
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);
$scp = Net::SCP->new( "$ip", "$user" ) or die "cannot scp $!";
$scp = new Net::SCP;
调用 Net::SCP
构造函数两次。第二次,它在没有主机名或用户 ID 的情况下调用它,不检查 return 值,并覆盖您之前看起来正确的调用。删除第二行。
您正在测试调用 scp
对象的构造函数是否成功,但您并未测试实际执行 scp
操作是否成功。
这条线可以改进:
$scp->scp($source, $destination);
该模块的文档指出 scp
returns 失败时为 false,并设置了 errstr
属性。因此,您可以按如下方式更改该行:
$scp->scp($source, $destination) or die 'scp failed: ', $scp->{errstr};
通过这样做,您应该获得有用的诊断信息,这是真正了解解决问题所必须采取的措施的唯一途径。
此外,与您的问题无关但值得一提:use Net::SCP qw(scp);
是错误的,因为它将 scp
函数导入到您的调用命名空间中。这是错误的原因是您正在使用 scp
的面向对象 "method call" 调用(换句话说,$scp->scp(...)
。调用 scp
的方法调用方式不不需要将任何内容导入您的调用命名空间。
Net::SCP documentation有两个例子说明如何调用scp()
:
use Net::SCP qw(scp iscp);
scp($source, $destination);
$scp = new Net::SCP;
$scp->scp($source, $destination);
您会注意到,这两个版本都没有说明如何指定主机名、用户名或密码,或者复制操作是本地到远程还是远程到本地。
事实是 Net::SCP 文档没有很好地描述如何使用 scp()。查看 source code for the module 表明:
scp()
子例程不使用传递给 Net::SCP 构造函数的任何值。
- scp() 调用
scp
命令行实用程序,将源和目标参数传递给该程序 verbatim.
因此,指定主机名、用户名、密码和复制方向的正确方法与 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);
这会生成一个格式为 "user@1.2.3.4:/tmp" 的目标,这是 scp
程序接受的格式。
如果您尝试进行远程到本地的复制,则应将“${user}\@${ip}:”字符串添加到 $source 而不是 $destination 之前。请注意,此处“@”前面有一个反斜杠,因为它在双引号字符串中很特殊。
顺便说一句,如果您使用两个本地路径名调用 scp
程序,它会调用系统的文件复制实用程序来执行本地复制操作。因此,您可能已将源文件名复制到 C:\tmp 或本地系统上的类似位置。
Windows 上的这个 Perl 脚本 运行,我正在尝试将文件从本地机器 scp 到 Linux 机器,它没有打印任何错误,但复制文件。
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);
$scp = Net::SCP->new( "$ip", "$user" ) or die "cannot scp $!";
$scp = new Net::SCP;
调用 Net::SCP
构造函数两次。第二次,它在没有主机名或用户 ID 的情况下调用它,不检查 return 值,并覆盖您之前看起来正确的调用。删除第二行。
您正在测试调用 scp
对象的构造函数是否成功,但您并未测试实际执行 scp
操作是否成功。
这条线可以改进:
$scp->scp($source, $destination);
该模块的文档指出 scp
returns 失败时为 false,并设置了 errstr
属性。因此,您可以按如下方式更改该行:
$scp->scp($source, $destination) or die 'scp failed: ', $scp->{errstr};
通过这样做,您应该获得有用的诊断信息,这是真正了解解决问题所必须采取的措施的唯一途径。
此外,与您的问题无关但值得一提:use Net::SCP qw(scp);
是错误的,因为它将 scp
函数导入到您的调用命名空间中。这是错误的原因是您正在使用 scp
的面向对象 "method call" 调用(换句话说,$scp->scp(...)
。调用 scp
的方法调用方式不不需要将任何内容导入您的调用命名空间。
Net::SCP documentation有两个例子说明如何调用scp()
:
use Net::SCP qw(scp iscp);
scp($source, $destination);
$scp = new Net::SCP;
$scp->scp($source, $destination);
您会注意到,这两个版本都没有说明如何指定主机名、用户名或密码,或者复制操作是本地到远程还是远程到本地。
事实是 Net::SCP 文档没有很好地描述如何使用 scp()。查看 source code for the module 表明:
scp()
子例程不使用传递给 Net::SCP 构造函数的任何值。- scp() 调用
scp
命令行实用程序,将源和目标参数传递给该程序 verbatim.
因此,指定主机名、用户名、密码和复制方向的正确方法与 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);
这会生成一个格式为 "user@1.2.3.4:/tmp" 的目标,这是 scp
程序接受的格式。
如果您尝试进行远程到本地的复制,则应将“${user}\@${ip}:”字符串添加到 $source 而不是 $destination 之前。请注意,此处“@”前面有一个反斜杠,因为它在双引号字符串中很特殊。
顺便说一句,如果您使用两个本地路径名调用 scp
程序,它会调用系统的文件复制实用程序来执行本地复制操作。因此,您可能已将源文件名复制到 C:\tmp 或本地系统上的类似位置。