在另一个脚本中使用system命令调用子例程

时间:2014-06-16 12:50:22

标签: windows perl exe

我在Windows 7 x86下运行perl,当我调用从另一个脚本执行外部命令的子例程时出现错误。

我有两个脚本, script1 有一个子程序,它执行一个程序(patt.exe)和 script2 ,它们通过require使用这个子程序。

当我运行 script1 时,它可以正常运行。但是当我尝试从 script2 中使用这个子例程时,我收到以下错误。

错误:

'patt.exe' is not recognized as an internal or external command, operable program or batch file.

SCRIPT1

#patt('file.txt');
sub patt { 
my $filename=shift@;
system("cmd.exe /c patt.exe -S $filename");
}
1;

SCRIPT2

require 'sub-directory/script1.pl';
patt('file.txt');

我应该提一下, script1 patt.exe 位于子目录(require 'sub-directory/script1.pl';)中,当我将所有文件放在同一目录中时( require 'script1.pl';)一切正常。如果我使用qx或将参数作为数组传递给脚本,则会出现此问题。

如果有人能帮助我,我会非常感激。

2 个答案:

答案 0 :(得分:0)

首先,您无需通过pratt.exe致电cmd.exe。你应该能够做到这一点:

system "patt.exe -S $filename";

错误来自系统命令无法找到命令patt.exe以执行它。试试这个:

 warn "WARN: \@INC: " . join "\n ", $ENV{PATH};

这将打印出将搜索可执行文件的所有目录。通常在Windows中,当前目录$PATH中的最后一个条目。我不是100%确定require如何与当前工作目录相关联。例如,可能是当您将子例程放在另一个目录中的文件中时,它找不到位于当前目录中的pratt.exe,因为当前目录现在是子例程所在的位置。

因此,您可能想要做的另一件事是使用Cwd导入cad命令:

use strict;     # Always! This will help point to errors.
use warnings;   # Always! This will help point to errors.
use Cwd;

sub patt { 
    my $filename = shift;

    warn "Current Working Directory is: " . cwd;
    warn "PATH is: " . join "\n", $ENV{PATH};

    my $error = system("cmd.exe /c patt.exe -S $filename");
    if ( $error ) {
       die qq(Patt failed.);
    }
}
1;

针对Windows PATH检查当前工作目录,看看是否能提示您patt未执行的原因。

答案 1 :(得分:0)

一种解决方案是您可以将当前工作目录更改为外部程序的目录。为此,您可以使用与您的程序共享同一目录的perl脚本的__FILE__变量。

当然,有一点需要注意的是,如果您使用此解决方案,您可能需要为$filename提供完全合格的路径:

use strict;
use warnings;

use Cwd;
use File::Spec;

sub patt {
    my $filename = shift;

    # Temporarily change cwd
    my $oldcwd = cwd;
    my ($vol, $path) = File::Spec->splitpath(__FILE__);
    chdir($path);

    # Execute program.  Note that $filename will likely need to be a fully qualified path
    system("patt.exe -S $filename");

    # Revert cwd
    chdir($oldcwd);
}

1;