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

发布于 2024-11-27 09:47:06 字数 584 浏览 1 评论 0原文

我有一个调用其他程序的 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 的正常输出或将其与此跟踪混合是可以接受的。

多谢。

I have a Perl script which invokes other programs, i.e. it calls system and/or exec and/or open with a pipe and/or uses the backtick operator.

Can I run this script in such a way that it will print out the arguments to each of the above so that I can see what it is calling into?

For example a program like this which I cannot modify

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

Invoked something perhaps like this

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

Which will in this case output

./foo argument1 argument2
./foo abc def

It is acceptable to throw away myscript.pl's normal output or blend it with this trace.

Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情感失落者 2024-12-04 09:47:06

这被认为是高级 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)中,然后使用 调用 perl -MShellTrace 开关。 (HT:帕尔曼):

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

This is considered advanced Perl, but you can define subroutines in the CORE::GLOBAL namespace at compile time and hijack Perl's builtin functions.
Calling functions in the CORE namespace will invoke the original builtin functions.

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;

To apply this feature to an arbitrary standalone script, you can put this code into a simple module (say, ShellTrace.pm), and then invoke perl with the -MShellTrace switch. (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
...
时光匆匆的小流年 2024-12-04 09:47:06

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

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

No, the system command does not put its executed command in any special variables.

#!/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*`;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文