【问题标题】:Can I capture shell invocations from Perl?我可以从 Perl 捕获 shell 调用吗?
【发布时间】:2011-08-02 14:16:13
【问题描述】:

我有一个调用其他程序的 Perl 脚本,即它使用管道调用 system 和/或 exec 和/或 open 和/或使用反引号运算符。

我能否以这样的方式运行这个脚本,它会打印出上述每个参数的参数,以便我可以看到它正在调用什么?

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

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

调用了类似这样的东西

perl --shell-trace-on ./myscript.pl

在这种情况下会输出

./foo argument1 argument2
./foo abc def

丢弃 myscript.pl 的正常输出或将其与此跟踪混合是可以接受的。

非常感谢。

【问题讨论】:

  • 所以你想让脚本看看shell扩展后的命令是什么样子的?
  • 我想捕获外部程序的执行及其参数。

标签: perl debugging shell shellexecute system-calls


【解决方案1】:

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

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):

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
...

【讨论】:

  • 令人印象深刻的技巧,但它需要修改脚本。有没有办法在这样建立环境的情况下调用脚本?
  • 是的 - 将这些更改放在 .pm 文件中(例如 ShellTrace.pm,并使用 perl -MShellTrace ./myscript.pl 调用您的脚本
【解决方案2】:

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

#!/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*`;

【讨论】:

  • 编辑澄清——脚本是不可变的。我正在寻找类似于strace 的解决方案。
猜你喜欢
  • 2019-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多