我正在尝试编写一个执行bash脚本的Perl程序。 Perl脚本看起来像这样
#!/usr/bin/perl
use diagnostics;
use warnings;
require 'userlib.pl';
use CGI qw(:standard);
ReadParse();
my $q = new CGI;
my $dir = $q->param('X');
my $s = $q->param('Y');
ui_print_header(undef, $text{'edit_title'}.$dir, "");
print $dir."<br>";
print $s."<br>";
print "Under Construction <br>";
use Cwd;
my $pwd = cwd();
my $directory = "/Logs/".$dir."/logmanager/".$s;
my $command = $pwd."/script ".$directory."/".$s.".tar";
print $command."<br>";
print $pwd."<br>";
chdir($directory);
my $pwd1 = cwd();
print $pwd1."<br>";
system($command, $directory) or die "Cannot open Dir: $!";
脚本失败并显示以下错误:
Can't exec "/usr/libexec/webmin/foobar/script
/path/filename.tar": No such file or directory at /usr/libexec/webmin/foobar/program.cgi line 23 (#3)
(W exec) A system(), exec(), or piped open call could not execute the
named program for the indicated reason. Typical reasons include: the
permissions were wrong on the file, the file wasn't found in
$ENV{PATH}, the executable in question was compiled for another
architecture, or the #! line in a script points to an interpreter that
can't be run for similar reasons. (Or maybe your system doesn't support #! at all.)
我已经检查过权限是否正确,我传递给我的bash脚本的tar文件是否存在,还是从命令行尝试运行我试图从Perl脚本运行的相同命令({ {1}})它运作正常。
答案 0 :(得分:9)
在Perl中,使用一个参数(在标量上下文中)调用system
并使用多个标量参数调用它(在列表上下文中)different things。
在标量上下文中,调用
system($command)
将启动一个外部shell并在其中执行$command
。如果$command
中的字符串有参数,它们也将被传递给调用。例如,
$command="ls /";
system($commmand);
将评估为
sh -c "ls /"
其中shell被赋予整个字符串,即带有所有参数的命令。此外,$command
将在设置所有常规环境变量的情况下运行。这可能是一个安全问题,请参阅here和here以了解原因。
另一方面,如果你用一个数组调用系统(在列表上下文中),Perl不会调用shell并给它$command
作为参数,而是尝试执行数组的第一个元素直接并将其他参数作为参数。所以
$command = "ls";
$directory = "/";
system($command, $directory);
将直接调用ls
,而不会在其间产生shell。
回到你的问题:你的代码说
my $command = $pwd."/script ".$directory."/".$s.".tar";
system($command, $directory) or die "Cannot open Dir: $!";
请注意$command
此处类似于/path/to/script /path/to/foo.tar
,其中参数已经是字符串的一部分。如果你在标量上下文中调用它
system($command)
一切都会正常,因为
sh -c "/path/to/script /path/to/foo.tar"
将以script
作为参数执行foo.tar
。但是如果你在列表上下文中调用它,它将尝试找到一个名为/path/to/script /path/to/foo.tar
的可执行文件,这将失败。
答案 1 :(得分:0)
我发现了问题。 更改了系统命令删除第二个参数,现在它正在工作
system($command) or die "Cannot open Dir: $!";
公平地说,我不明白第一个例子出了什么问题,但现在工作正常,如果有人能解释可能有趣的理解
答案 2 :(得分:0)
在perl中有多种方法可以执行bash命令/脚本。