我正在尝试编写一个将执行 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 脚本运行的相同命令(/usr/libexec/webmin/foobar/script/path/filename.tar
) 并且它工作正常。
最佳答案
在 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"
将以 foo.tar
作为参数执行 script
。但是,如果您在列表上下文中调用它,它将尝试定位名为 /path/to/script/path/to/foo.tar
的可执行文件,这将失败。
关于linux - 从 Perl 程序执行 bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31285458/