Windows 在另一个脚本中使用系统命令调用子例程

Windows 在另一个脚本中使用系统命令调用子例程,windows,perl,exe,Windows,Perl,Exe,我在Windows7x86下运行perl,当我调用从另一个脚本执行外部命令的子程序时出错 我有两个脚本,script1有一个执行程序的子程序(patt.exe),script2通过require使用这个子程序 当我运行script1时,它工作正常。但是当我试图从script2内部使用这个子例程时,我得到了以下错误 错误: 'patt.exe' is not recognized as an internal or external command, operable program or bat

我在Windows7x86下运行perl,当我调用从另一个脚本执行外部命令的子程序时出错

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

当我运行script1时,它工作正常。但是当我试图从script2内部使用这个子例程时,我得到了以下错误

错误:

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

#patt('file.txt');
sub patt { 
my $filename=shift@;
system("cmd.exe /c patt.exe -S $filename");
}
1;
require 'sub-directory/script1.pl';
patt('file.txt');
脚本2

#patt('file.txt');
sub patt { 
my $filename=shift@;
system("cmd.exe /c patt.exe -S $filename");
}
1;
require 'sub-directory/script1.pl';
patt('file.txt');
我应该提到,script1和patt.exe位于子目录(
require'sub directory/script1.pl';
)中,当我将所有文件放在同一目录(
require'script1.pl';
)中时,一切正常。如果使用
qx
或将参数作为数组传递给脚本,则此问题仍然存在


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

首先,您不需要通过
cmd.exe
调用
pratt.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路径检查当前工作目录,看看这是否提示您为什么未执行
patt

一种解决方案是,您可以将当前工作目录更改为外部程序的工作目录。要做到这一点,您可以利用perl脚本中与您的程序共享同一目录的
\uuu FILE\uu
变量

当然,需要注意的是,如果使用此解决方案,您可能需要提供指向
$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;

-f“patt.exe”或die“必须在其他文件夹中”就在系统的前面call@mpapec,当我将脚本和.exe文件放在同一个目录中时,它可以正常工作。目前“script1”和“patt.exe”位于sub_目录中,在script2中我提到“需要‘sub_目录/script1.pl’”。有什么可能是错的?!。我是否可以将带有子程序脚本的.exe文件放在单独的文件夹中?这是windows的问题;使用完整的.exe路径或将其放在系统路径中。谢谢。可执行文件不在我的系统路径中,我不想(我在主工作PC中没有权限)设置它。我很清楚,第二个脚本在调用第一个脚本时,运行其目录中的所有子例程,而不是script1子目录中的所有子例程。在这些情况下.exe文件必须位于script2目录中。我有很多.exe文件,希望将它们排列在子目录而不是主目录中。然后,您必须在系统调用中包含可执行文件的目录名。您可以尝试:更改
$ENV{PATH}
变量本身以包含所需的目录。您可以在Unix上执行此操作,并且它将保持不变,但我不知道这是否在Windows上有效。附加目录,看看是否可以访问可执行文件。在Unix上,程序退出后会重置路径。谢谢@Miller,您的解决方案非常有效。我已经替换了
my($vol,$path)=File::Spec->splitpath(\uuu File\uuu)
我的$path=\u_文件\u_$路径=~s/\/.+?\.pl/并且所有事情都很好地工作。