说我有这个名为simple.pl的perl“程序”:
#!/usr/bin/perl
use xyz; # xyz is bogus and doesn't exist
我也有这个名为simple2.pl的“程序”:
#!/usr/bin/perl
system("simple.pl");
my $abc = `simple.pl`;
printf("abc %s\n", $abc);
对于系统和反引号,我收到此消息:
Can't exec "simple.pl": No such file or directory at scripts/perl/simple2.pl line 7.
Can't exec "simple.pl": No such file or directory at scripts/perl/simple2.pl line 9.
对于调用simple2.pl的用户不是很有用。有没有办法获得更有用的信息?
请注意。 simple.pl确实存在于当前目录中。真正的问题是simple.pl不能编译。 simple2通过说简单不存在来回应。这是一个误导性的信息。
如果我有办法甚至捕获可能是开始的编译消息。
答案 0 :(得分:6)
这意味着系统无法在PATH上找到名为“simple.pl”的可执行文件。如果simple.pl在当前目录中,您可以尝试将“simple.pl”更改为“./simple.pl”。
实际上,我没有看到如何使这条消息更具描述性。如果你是perl,你会如何报告此错误?
顺便说一句,我不会尝试从simple2.pl内部运行“simple2.pl”:)答案 1 :(得分:3)
是的,检查文件是否存在且是否可执行,如果不存在,则打印更具描述性的消息。
unless (-ex $filename) {
print "I am unable to execute file $filename.";
}
答案 2 :(得分:2)
如果perl说它找不到文件,那么就找不到该文件了。而问题是你的代码更多。看看这个例子。
sidburn@sid:~/perl$ cat test.pl #!/usr/bin/env perl use strict; use warnings; use xyz; sidburn@sid:~/perl$ cat test2.pl #!/usr/bin/env perl use strict; use warnings; system('test.pl'); sidburn@sid:~/perl$ cat test3.pl #!/usr/bin/env perl use strict; use warnings; system('./test.pl');
如果你执行test2.pl,你会得到:
sidburn@sid:~/perl$ ./test2.pl Can't exec "test.pl": No such file or directory at ./test2.pl line 4.
如果你执行test3.pl,你会得到:
sidburn@sid:~/perl$ ./test3.pl Can't locate xyz.pm in @INC (@INC contains: /home/sidburn/perl510/lib/5.10.1/i686-linux /home/sidburn/perl510/lib/5.10.1 /home/sidburn/perl510/lib/site_perl/5.10.1/i686-linux /home/sidburn/perl510/lib/site_perl/5.10.1 .) at ./test.pl line 4. BEGIN failed--compilation aborted at ./test.pl line 4.
如果您没有提供相对路径或绝对路径,那么perl会在$ PATH环境变量中查找该命令。如果它不存在则无法找到该文件。
如果它在当前目录中,则需要提供“./”。但请注意,“当前目录”并不表示脚本所依赖的目录。
如果你想要后者,那么你可能想要做一个
use FindBin;用这个你可以做这样的事情:
#!/usr/bin/env perl use strict; use warnings; use FindBin; use File::Spec::Functions; my $exe = catfile($FindBin::RealBin, 'test.pl'); print $exe, "\n"; system($exe);
如果要检查系统是否正确返回,则需要检查system()命令的返回值或$?后来保留了价值。
if ( $? != 0 ) { die "Cannot execute $exe.\n"; }
如果要取消程序中的消息,则需要在使用system()启动程序之前重定向STDOUT,STDERR。
或使用IPC::System::Simple之类的内容 或IPC :: Open3(在核心)。
答案 3 :(得分:1)
启用warnings
pragma的奖励积分!有一个upvote!
您希望使用反引号或qx//
来捕获外部程序的输出,而不是system
。要替换对您的用户有意义的自己的错误消息(为您提供更多要点!),那么您可以执行某些操作,如
#! /usr/bin/perl
use strict;
use warnings;
no warnings 'exec';
chomp(my $abc = `simple2.pl`);
if ($? == 0) {
printf("abc %s\n", $abc);
}
else {
die "$0: unable to calculate abc\n";
}
如果你不熟悉,$?
是
<强> $ CHILD_ERROR 强>
$?
最后一次管道关闭,反引号命令,成功调用wait
或waitpid
或system
运算符返回的状态。
当$?
为零时,表示成功。
请记住,warnings
编译指示是词法,因此,不是禁用整个程序的警告,而是只为一个子程序执行此操作:
sub calculate_abc {
no warnings 'exec';
# ...
}
答案 4 :(得分:1)
如果你试图执行一些你知道的Perl脚本,为什么不直接调用解释器而不是处理知道如何执行文件的系统呢?
my $file = 'simple.pl';
-e $file or die "file '$file' not found";
system "perl $file";
# or
print `perl $file`;
使用运行当前脚本的相同perl安装运行:
system "$^X $file"; # or `$^X $file`
$^X
是一个特殊的Perl变量,它包含正在运行的解释器的文件名。
答案 5 :(得分:0)
我有完全相同的问题并且发现没有安装perl。所以bash脚本试图在没有解释器的情况下执行perl。
ls /usr/bin/perl
答案 6 :(得分:0)
尝试指定“ simple.pl”文件的完整路径。