Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl scp创建远程目录并显示进度_Perl - Fatal编程技术网

Perl 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_

我对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_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(\&copy_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";