Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以从Perl捕获shell调用吗?_Perl_Debugging_Shell_Shellexecute_System Calls - Fatal编程技术网

我可以从Perl捕获shell调用吗?

我可以从Perl捕获shell调用吗?,perl,debugging,shell,shellexecute,system-calls,Perl,Debugging,Shell,Shellexecute,System Calls,我有一个调用其他程序的Perl脚本,即它使用管道调用system和/或exec和/或open,和/或使用backtick操作符 我能否以这样一种方式运行这个脚本,它将打印出上面每个脚本的参数,以便我可以看到它调用了什么 例如,像这样的程序,我无法修改 #!/usr/bin/perl sub get_arg {return "argument$_[0]";} system "./foo", get_arg(1), get_arg(2); print `./foo abc def`; 可能是这样的

我有一个调用其他程序的Perl脚本,即它使用管道调用
system
和/或
exec
和/或
open
,和/或使用backtick操作符

我能否以这样一种方式运行这个脚本,它将打印出上面每个脚本的参数,以便我可以看到它调用了什么

例如,像这样的程序,我无法修改

#!/usr/bin/perl
sub get_arg {return "argument$_[0]";}
system "./foo", get_arg(1), get_arg(2);
print `./foo abc def`;
可能是这样的

perl—在./myscript.pl上的shell跟踪

在这种情况下,它将输出

./foo argument1 argument2
./foo abc def
丢弃myscript.pl的正常输出或将其与此跟踪混合是可以接受的


非常感谢。

否,系统命令不会将其执行的命令放入任何特殊变量中

#!/usr/bin/perl
sub get_arg {return "argument$_[0]";}
my $command = './foo ' . join(' ', get_arg(1), get_arg(2));
print "$command\n";
my $resp = `$command`; # or system($command);
print `ls *bar*`;

这被认为是高级Perl,但您可以在编译时在
CORE::GLOBAL
命名空间中定义子例程,并劫持Perl的内置函数。 调用
核心
命名空间中的函数将调用原始内置函数

BEGIN {
    # have to use a BEGIN block so these functions are defined before
    # run time
    *CORE::GLOBAL::system = sub {
        print STDERR "about to invoke system @_\n";
        return CORE::system(@_);
    };
    *CORE::GLOBAL::qx = sub {
        print STDERR "about to invoke qx/backticks @_\n";
        return CORE::qx(@_);
    };
    *CORE::GLOBAL::exec = sub { ... };
};
system("sleep 5");
print `ls`;
1;
要将此功能应用于任意独立脚本,可以将此代码放入一个简单的模块(例如,
ShellTrace.pm
),然后使用
-MShellTrace
开关调用
perl
。(HT:perlman):


你想让脚本看到shell扩展后命令的样子吗?我想捕获外部程序的执行及其参数。编辑以澄清——脚本是不可变的。我正在寻找一个类似于
strace
的解决方案。这是一个令人印象深刻的技巧,但它需要修改脚本。有没有一种方法可以在这样建立的环境中调用未更改的脚本?是的-将这些更改放在
.pm
文件中(例如
ShellTrace.pm
,并使用
perl-MShellTrace./myscript.pl
调用脚本
package ShellTrace;
BEGIN {
    *CORE::GLOBAL::system = sub { ... };
    *CORE::GLOBAL::qx = sub { ... };
    *CORE::GLOBAL::exec = sub { ... };
    *CORE::GLOBAL::open = sub { ... };
}
1;

$ perl -MShellTrace ./myscript.pl
about to invoke system ./foo argument1 argument2 
about to invoke qx/backticks ./foo abc def
...