如何在不硬编码持续时间的情况下暂停Perl处理?

如何在不硬编码持续时间的情况下暂停Perl处理?,perl,dynamic,duration,Perl,Dynamic,Duration,我有一个包含以下代码段的Perl脚本,它调用系统shell通过SFTP获取一些文件,并使用WinZip解压: # Run script to get files from remote server system "exec_SFTP.vbs"; # Unzip any files that were retrieved foreach $zipFile (<*.zip>) { system "wzunzip $zipFile"; } 在解压步骤之前,但这假设SFTP

我有一个包含以下代码段的Perl脚本,它调用系统shell通过SFTP获取一些文件,并使用WinZip解压:

#  Run script to get files from remote server
system "exec_SFTP.vbs";

#  Unzip any files that were retrieved
foreach $zipFile (<*.zip>) {
    system "wzunzip $zipFile";
}
在解压步骤之前,但这假设SFTP连接将在60秒内完成,这有时可能是一个严重的高估,有时是一个低估

在继续解压步骤之前,是否有更合理的方法使Perl暂停直到SFTP连接关闭

编辑:响应者对VB脚本的使用,而不是让Perl进行文件传输提出了质疑(这是合理的)。它与安全性有关——VB脚本由其他人维护,并被授权执行SFTP。

请看

IPC::Open3-使用Open3()打开读取、写入和错误处理的进程

看看

IPC::Open3-使用Open3()打开读取、写入和错误处理的进程


检查*.vbs文件中的代码。
系统
函数等待子进程完成,然后继续执行。您的*.vbs文件似乎正在执行后台任务以进行FTP并立即返回。

检查*.vbs文件中的代码。
系统
函数等待子进程完成,然后继续执行。您的*.vbs文件似乎正在执行后台任务以进行FTP并立即返回。

您需要一种方法让Perl等待SFTP传输完成,但由于您的脚本当前已编写,Perl无法知道这一点。(看起来您正在组合至少两种脚本语言和一个(GUI?)SFTP客户端;这可以工作,但并不完全可靠或健壮。为什么要使用VBscript启动SFTP传输?)

我可以想出四个选择:

  • 您的Perl脚本可以使用类似CPAN的模块自行完成SFTP传输,而不是生成无法跟踪其状态的外部作业
  • 您的Perl脚本可能会生成一个命令行SFTP实用程序(如),该实用程序在传输完成之前不会返回
  • 或者将exec_SFTP.vbs脚本更改为在传输完成之前不返回
  • 如果您当前使用的是图形化SFTP客户端,并且由于任何原因无法切换,我建议您使用类似于Perl的脚本语言。AutoIt具有等待windows更改状态等功能,因此它可以更轻松地监视活动的完成情况

  • 选项1或2将是最健壮和可靠的。

    您需要一种方法让Perl等待SFTP传输完成,但由于您的脚本目前正在编写,Perl无法知道这一点。(看起来您正在组合至少两种脚本语言和一个(GUI?)SFTP客户端;这可以工作,但并不完全可靠或健壮。为什么要使用VBscript启动SFTP传输?)

    我可以想出四个选择:

  • 您的Perl脚本可以使用类似CPAN的模块自行完成SFTP传输,而不是生成无法跟踪其状态的外部作业
  • 您的Perl脚本可能会生成一个命令行SFTP实用程序(如),该实用程序在传输完成之前不会返回
  • 或者将exec_SFTP.vbs脚本更改为在传输完成之前不返回
  • 如果您当前使用的是图形化SFTP客户端,并且由于任何原因无法切换,我建议您使用类似于Perl的脚本语言。AutoIt具有等待windows更改状态等功能,因此它可以更轻松地监视活动的完成情况

  • 选项1或2最可靠。

    我能建议的最好方法是修改exec_SFTP.vbs,使其仅在文件传输完成后退出<代码>系统等待它调用的程序完成,这样可以解决您的问题:

    system LIST system PROGRAM LIST Does exactly the same thing as "exec LIST", except that a fork is done first, and the parent process waits for the child process to complete. 系统列表 系统程序表 执行与“执行列表”完全相同的操作,除了 首先完成一个fork,然后父进程 等待子进程完成。
    我建议的最好方法是修改exec_SFTP.vbs,使其仅在文件传输完成后退出<代码>系统等待它调用的程序完成,这样可以解决您的问题:

    system LIST system PROGRAM LIST Does exactly the same thing as "exec LIST", except that a fork is done first, and the parent process waits for the child process to complete. 系统列表 系统程序表 执行与“执行列表”完全相同的操作,除了 首先完成一个fork,然后父进程 等待子进程完成。 在运行命令的shell返回之前不会返回;这对于启动图形程序和文件关联可能是错误的

    查看是否有以下任何帮助

    system('cscript exec_SFTP.vbs');
    
    use Win32::Process;
    use Win32;
    Win32::Process::Create(my $proc, 'wscript.exe',
            'wscript exec_SFTP.vbs', 0, NORMAL_PRIORITY_CLASS, '.');
    $proc->Wait(INFINITE);
    
    在运行命令的shell返回之前不会返回;这对于启动图形程序和文件关联可能是错误的

    查看是否有以下任何帮助

    system('cscript exec_SFTP.vbs');
    
    use Win32::Process;
    use Win32;
    Win32::Process::Create(my $proc, 'wscript.exe',
            'wscript exec_SFTP.vbs', 0, NORMAL_PRIORITY_CLASS, '.');
    $proc->Wait(INFINITE);
    

    也许这是一个愚蠢的问题,但为什么不使用和Perl模块下载和解压文件呢?

    也许这是一个愚蠢的问题,但为什么不使用和Perl模块下载和解压文件呢?

    在一个完美的世界中,您的脚本将被重写以使用和

    一种丑陋的快速黑客方式可能是在第一次系统调用之前创建一个touch文件,修改sftp抓取脚本,在完成后删除该文件,然后像这样等待一段时间

    while(-e 'touch.file') {
        sleep 5;
    }
    
    # foreach [...]
    

    当然,如果.vbs出现故障,导致touchfile未删除,以及其他许多不良副作用,您需要小心。这将是一个快速解决方案(如果其他建议都不起作用),直到您有时间在不调用system()的情况下重写为止。

    在一个完美的世界中,您的脚本将被重写以使用和

    一种丑陋的快速黑客方式可能是在第一次系统调用之前创建一个touch文件,修改sftp抓取脚本,在完成后删除该文件,然后像这样等待一段时间

    while(-e 'touch.file') {
        sleep 5;
    }
    
    # foreach [...]
    
    当然,你会的