是否有可能让'exec'在Perl中使用'$ SHELL -c'而不是'/ bin / sh -c'?

时间:2009-08-09 14:51:33

标签: perl unix exec

在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 /的所有变体中传播SH。但大多数时候我只是好奇,现在对如何将解决方案扩展到qx感到好奇。此外,由于我对非unix平台一无所知,所以我想避免在解决方案中对备用shell的路径进行硬编码。

4 个答案:

答案 0 :(得分: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 $$';

答案 1 :(得分:3)

如果只传递一个参数,那么

execsystem将使用shell(在非UNIX系统上可能不是/bin/sh)。 (详情见perlfunc

您可能希望查看IPC::Run3作为system

的替代方案

答案 2 :(得分:3)

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

sub my_exec {
    exec $ENV{SHELL}, '-c', @_;
    }

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

答案 3 :(得分:-5)

exec不使用/ bin / sh

它只执行您指定的程序。没有炮弹。

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