Perl scp创建远程目录并显示进度
我对perl脚本非常陌生。使用下面的代码,我尝试循环此系统调用命令以打印(==),直到远程scp完成。但事实证明,直到scp完成,循环才会执行。任何帮助都将不胜感激Perl scp创建远程目录并显示进度,perl,Perl,我对perl脚本非常陌生。使用下面的代码,我尝试循环此系统调用命令以打印(==),直到远程scp完成。但事实证明,直到scp完成,循环才会执行。任何帮助都将不胜感激 $server = "myserver.com" $download_from = "/var/tmp"; $download_to = "/tmp" chomp ($scp_user = <STDIN>); $rc = system ("scp -r ${scp_user}\@${server}:{download_
$server = "myserver.com"
$download_from = "/var/tmp";
$download_to = "/tmp"
chomp ($scp_user = <STDIN>);
$rc = system ("scp -r ${scp_user}\@${server}:{download_from} ${download_to} >> $logfile 2>&1");
my count = 0;
while (( $rc == 0) && ( $count < 120 ))
{
print "=" ;
sleep 5;
$count = $count = 1;
$rc = system ("scp -r ${scp_user}\@${server}:{download_from} ${download_to} >> $logfile 2>&1");
}
$server=“myserver.com”
$download_from=“/var/tmp”;
$download_to=“/tmp”
chomp($scp_user=);
$rc=system(“scp-r${scp_user}\@${server}:{download_from}${download_to}>>$logfile 2>&1”);
我的计数=0;
而($rc==0)和($count<120))
{
打印“=”;
睡眠5;
$count=$count=1;
$rc=system(“scp-r${scp_user}\@${server}:{download_from}${download_to}>>$logfile 2>&1”);
}
这里要做的是调用scp(在由系统调用启动的子shell中),完成后检查退出代码,如果它为零(通常表示成功),则再次调用它
顺便说一句,行$count=$count=1
并没有像我假设的那样递增,它只是将其设置为1。您可能打算编写$count++代码>
我假设您希望每5秒打印一个等号,直到命令完成。要做到这一点,您需要并行运行该命令,并检查它何时完成
我想你的代码永远不会停止,只是每隔5秒左右打印等号,直到你感到厌烦并终止它为止。一种解决方案是在程序打印进度时使用线程复制文件
这里有一个例子
use Config;
use threads;
$Config{useithreads} or die('Recompile perl with threads to run this program');
$| = -1; # non buffered output.
my $thread = threads->create(\©_file); # Spawn the thread.
while (threads->list(threads::runing)) { # While it is running.
print "="; # show the progress.
sleep 1; # sleep to give it a chance to run.
}
$thread->join(); # Cleanup the thread.
# Function to do the file copy.
sub copy_file {
system 'scp /tmp/junk.junk localhost:/tmp/junk.bunk >/dev/null 2>&1';
}
这里是另一个使用fork而不是线程的解决方案。。。
.. 并处理密码。(尽管我确实建议使用公钥)
#/usr/bin/perl
严格使用;
使用警告;
使用Net::SCP::Expect;
使用Term::ReadKey;
使用POSIX“:sys_wait_h”;
我的$user;
我的$pw;
打印“输入用户名:”;
chomp($user=);
ReadMode('noecho');
打印“输入密码:”;
chomp($pw=);
读取模式(“还原”);
我的$scpe=Net::SCP::Expect->new;
$scpe->login($user,$pw);
$| = -1;
我的$pid=叉子;
如果($pid){
打印“父项”\n;
}elsif($pid==0){
$scpe->scp('/tmp/junk','localhost:/tmp/junk2');
出口0;
}否则{
死“不能叉”\n;
}
我的孩子;
做{
$child=waitpid(-1,WNOHANG);
睡眠1;
打印“-”;
}而$child>=0;
打印“\n文件已被复制。\n”;
欢迎使用SO和perl。请在每个perl脚本的顶部包含和。这是使自己成为一名更好的程序员并使编程生活更轻松的第一件事。Perl的优势之一是提供了可以完成大多数可以想象的事情的模块,这样您就不必从头再来了。在这种情况下,像这样的事情可能会做你想做的。如果您确实想自己运行scp
命令,那么我建议您使用类似的方法,而不是在system()
中使用管道。谢谢John,看起来我正在使用的这个perl版本中没有线程模块。Perl 5.8.4#perldoc threads找不到关于“threads”的文档。我可以使用fork而不是threads吗,因为threads模块似乎没有与我正在运行的Perl版本一起安装?我正在使用的Perl 5.8.4似乎没有threads模块。这可以用叉子来代替吗?也许吧。我先试过了,但我的mac电脑似乎无法进行非阻塞等待,所以我无法让它工作。
#!/usr/bin/perl
use strict;
use warnings;
use Net::SCP::Expect;
use Term::ReadKey;
use POSIX ":sys_wait_h";
my $user;
my $pw;
print "Enter Username: ";
chomp($user = <STDIN>);
ReadMode('noecho');
print "Enter Password: ";
chomp($pw = <STDIN>);
ReadMode('restore');
my $scpe = Net::SCP::Expect->new;
$scpe->login($user, $pw);
$| = -1;
my $pid = fork;
if ($pid) {
print "parent\n";
} elsif ($pid == 0) {
$scpe->scp('/tmp/junk','localhost:/tmp/junk2');
exit 0;
} else {
die "Couldnt fork\n";
}
my $child;
do {
$child = waitpid(-1, WNOHANG);
sleep 1;
print "-";
} while $child >= 0;
print "\nFile has been copied.\n";