3

我在使用 Perl 时遇到了这个奇怪的问题。我正在尝试从我的 Perl 脚本中执行一个外部程序,这个外部程序将字符串 + 通配符作为参数。我的 Perl 程序看起来像这样

my $cmd_to_run = 'find-something-in-somedb myname* |' 
open(procHandle, $cmd_to_run); # I am using open because I want to 
                               # parse the output using pipes

出于某种奇怪的原因,运行这个 Perl 脚本(在 Windows 下)调用open函数最终会出现错误:

'sqlselect' is not recognized as an internal or external command

我猜想它与*我的命令字符串中的存在有关,因此我删除了它,现在我的命令字符串看起来像这样

my $cmd_to_run = 'find-something-in-somedb myname|'

现在,当我运行我的 Perl 脚本时,它工作得非常好。仅当存在通配符时才会出现问题。

需要注意的几点:

  1. 我在同一个 cmd 提示符(我正在执行这个 perl 脚本的地方)中用通配符 char 运行了相同的命令,它工作得非常好..

  2. 当我在 C 中使用 Windows 中的 _open 函数对其进行编程时,相同的命令有效。

  3. 问题似乎只有当通配符 * 存在时,至少这是我的猜测

  4. 不,我没有在 Unix 中尝试过这个..

有什么线索???

编辑:我发现这与 ENV 有关。我尝试运行的程序仅在搜索字符串中存在“*”通配符时才使用“sqlselect”... find-something-in-somedb 和 sqlselect 都存在于同一位置。在这种情况下,perl 如何找到“find-in-db”而不是“sqlselect”

抱歉,我意识到原来的问题现在变成了其他问题。与“ENV”有关,与通配符无关*

4

3 回答 3

6

建议使用open的 3 参数形式

open(procHandle, '-|', 'find-something-in-somedb', 'myname*');

因为它绕过了外壳(它将执行*扩展)。

但是,在 Windows 上,应用程序通常会执行自己的引号解析和*扩展,因此您可能需要

open(procHandle, '-|', 'find-something-in-somedb', '"myname*"');

甚至

open(procHandle, '-|', 'find-something-in-somedb "myname*"');

因为我不确定 Perl 是如何以及何时将事情交给cmd.

于 2009-07-10T20:17:08.047 回答
3

Perl 很可能正在扩展通配符本身,而您不想这样做。ehemient提供的答案非常好,但是为了调试它,请尝试调用这个非常简单的程序:

print join ' ', @ARGV;

把它放到它自己的文件中,然后从你的原始程序中调用它(我命名为我的 argv.pl):

my $cmd_to_run = './argv.pl myname* |' 
open(procHandle, $cmd_to_run); 

这将在你的平台上明确地告诉你 Perl 是如何解析事物的。在 Unix 上,* 被扩展以匹配当前工作目录中的文件。虽然不确定Windows。

于 2009-07-10T21:00:28.240 回答
0

如果你使用三个参数会发生什么open

open my $procHandle, '-|', 'find-something-in-somedb myname*'
    or die "Cannot open pipe: $!";
于 2009-07-10T20:16:32.277 回答