Как получить сценарий оболочки [переменные среды] в Perl-сценарии, не разветвляясь подоболочка? - PullRequest
8 голосов
/ 26 июля 2011

Я хочу вызвать "env.sh" из "my_perl.pl" без разветвления подоболочки.Я пытался с backtics и системой, как это -> system (. env.sh) [точка пространства env.sh], однако не будет работать.

Ответы [ 3 ]

14 голосов
/ 26 июля 2011

Дочерние среды не могут изменять родительские среды.Лучше всего проанализировать env.sh изнутри кода Perl и установить переменные в %ENV:

#!/usr/bin/perl

use strict;
use warnings;

sub source {
    my $name = shift;

    open my $fh, "<", $name
        or die "could not open $name: $!";

    while (<$fh>) {
        chomp;
        my ($k, $v) = split /=/, $_, 2;
        $v =~ s/^(['"])(.*)\1/$2/; #' fix highlighter
        $v =~ s/\$([a-zA-Z]\w*)/$ENV{$1}/g;
        $v =~ s/`(.*?)`/`$1`/ge; #dangerous
        $ENV{$k} = $v;
    }
}

source "env.sh";

for my $k (qw/foo bar baz quux/) {
    print "$k => $ENV{$k}\n";
}

Учитывая

foo=5
bar=10
baz="$foo$bar"
quux=`date +%Y%m%d`

при печати

foo => 5
bar => 10
baz => 510
quux => 20110726

Код может обрабатывать только простые файлы (например, он не обрабатывает if операторов или foo=$(date)).Если вам нужно что-то более сложное, тогда написание обертки для вашего Perl-скрипта с исходными кодами env.sh - это правильный путь (это также, вероятно, правильный путь в первую очередь).

Другойпричина для получения env.sh перед выполнением сценария Perl заключается в том, что установка переменных среды в Perl может произойти слишком поздно для модулей, которые ожидают их увидеть.

В файле foo:

#!/bin/bash

source env.sh

exec foo.real

где foo.real - ваш Perl-скрипт.

2 голосов
/ 05 мая 2012

Попробуйте это (пример кода Unix):

CD / TMP

vi s

#!/bin/bash
export blah=test

vi t

#!/usr/bin/perl

if ($ARGV[0]) {
    print "ENV second call is : $ENV{blah}\n";
} else {
    print "ENV first call is : $ENV{blah}\n";
    exec(". /tmp/s; /tmp/t 1");
}

chmod 777 с т

. / Т

ENV первый вызов:

ENV второй вызов: тест

Хитрость заключается в том, чтобы сначала использовать exec для создания исходного сценария bash, а затем снова вызвать свой сценарий perl с аргументом, чтобы вы знали, что вас вызывают во второй раз.

2 голосов
/ 25 апреля 2012

Вы можете использовать произвольно сложные сценарии оболочки, выполнив их с соответствующей оболочкой, выгрузив их среду в стандартный вывод в том же процессе и проанализировав его в perl.Целесообразно вводить выходные данные во что-то отличное от% ENV или фильтровать конкретные значения, чтобы вы не меняли такие вещи, как PATH, которые могут иметь интересные побочные эффекты в других местах.Я исключил стандартный вывод и ошибку из порожденного сценария оболочки, хотя их можно перенаправить во временные файлы и использовать для диагностического вывода в сценарии perl.

foo.pl:

#!/usr/bin/perl
open SOURCE, "bash -c '. foo.sh >& /dev/null; env'|" or
die "Can't fork: $!";

while(<SOURCE>) {
if (/^(BAR|BAZ)=(.*)/) {
    $ENV{$1} = ${2} ;
}
}

close SOURCE;

print $ENV{'BAR'} . "\n";

foo.sh: экспорт BAR = баз

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...