从Perl程序执行bash脚本

时间:2015-07-08 06:52:37

标签: linux bash perl shell

我正在尝试编写一个执行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}})它运作正常。

3 个答案:

答案 0 :(得分:9)

在Perl中,使用一个参数(在标量上下文中)调用system并使用多个标量参数调用它(在列表上下文中)different things

在标量上下文中,调用

system($command)

将启动一个外部shell并在其中执行$command。如果$command中的字符串有参数,它们也将被传递给调用。例如,

$command="ls /";
system($commmand);

将评估为

sh -c "ls /"

其中shell被赋予整个字符串,即带有所有参数的命令。此外,$command将在设置所有常规环境变量的情况下运行。这可能是一个安全问题,请参阅herehere以了解原因。

另一方面,如果你用一个数组调用系统(在列表上下文中),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命令/脚本。

  1. 系统
  2. backquate
  3. EXEC