3

在 Perl 中,是否可以让 'exec'、'system' 和 'qx' 使用 /bin/sh 以外的 shell(不使用像 'exec "$SHELL -c ..."' 这样的结构,并且不使用重新编译perl)?

编辑:这个问题的动机是一个bash脚本,它执行'export -f foo',然后在子shell中使用perl通过'system“foo”'直接调用该函数。我不确定这种技术是否适用于所有 sh,虽然 'system "/bin/bash -c foo"' 可能在那种情况下工作,但我不希望导出的函数通过 /bin/ 的所有变体传播嘘。但大多数时候我只是好奇,现在很好奇如何将解决方案扩展到 qx。另外,由于我对非 unix 平台一无所知,我想避免在解决方案中硬编码到备用 shell 的路径。

4

4 回答 4

6

您可以覆盖execsystem。请参阅perldoc perlsub详细信息,但这大致是您想要的(以一些我不想尝试修复的引用错误为模):

#!/usr/bin/perl

use strict;
use warnings;

use subs qw/system/;

sub system {
    #handle one arg version:
    if (@_ == 1) {
        return CORE::system "$ENV{SHELL} -c $_[0]";
    }
    #handle the multi argument version
    return CORE::system @_;
}

print "normal system:\n";
system "perl", "-e", q{system q/ps -ef | grep $$/};

print "overloaded system:\n";
system 'ps -ef | grep $$';
于 2009-08-09T17:12:59.020 回答
3

exec如果您只向它传递一个参数,system它将使用 shell(可能不会/bin/sh在非 UNIX 系统上)。(详细说明见perlfunc

您可能想看看IPC::Run3作为替代system

于 2009-08-09T16:09:33.373 回答
3

你为什么不想使用'exec "$SHELL -c ..."'?如果您不想每次调用 exec 或 system 时都看到该代码,只需将其隐藏在子例程中即可。这就是他们的目的。:)

子我的执行{
    执行 $ENV{SHELL}, '-c', @_;
    }

但是,如果您想这样做,我建议以某种方式清理 $ENV{SHELL} 以便人们不会通过设置奇怪的值来对您的脚本做奇怪的事情。您可能希望确保 shell 列在 /etc/shells 中,或者您的系统以任何方式列出已批准的登录 shell。您还需要做更多的工作来使这种污染变得干净,如果您要将数据发送到另一个进程,您可能应该这样做。

于 2009-08-10T09:35:34.060 回答
-5

exec 不使用 /bin/sh

它只是执行您指定的程序。没有贝壳。

如果你想让它通过一个外壳,你必须自己做。

于 2009-08-09T15:53:15.153 回答