Пусть Perl выполняет сценарий оболочки и принимает переменные env - PullRequest
4 голосов
/ 10 апреля 2011

У меня есть сценарий оболочки, который не выполняет ничего, кроме установки нескольких переменных среды:

export MYROOTDIR=/home/myuser/mytools
export PATH=$MYROOTDIR/bin:$PATH
export MYVERSION=0.4a

У меня есть сценарий perl, и я хочу, чтобы сценарий perl каким-то образом заставлял сценарий perl работать сenv vars перечислены в сценарии оболочки.Мне нужно, чтобы это происходило из сценария perl, однако я не хочу, чтобы вызывающий perlscript сначала должен был вручную вводить сценарий.

При попытке запустить

system("sh myshell.sh")

env vars не "распространяются" на процесс, выполняющий скрипт perl.

Есть ли способ сделать это?

Ответы [ 5 ]

4 голосов
/ 10 апреля 2011

Чтобы правильно ответить на этот вопрос, мне нужно знать немного больше.

  • Можно ли вообще запускать скрипт оболочки из скрипта perl?
  • Является ли переменнаявсе назначения в форме export VAR=value (т.е. с фиксированными назначениями, без подстановок переменных или подстановок команд)?
  • Делает ли сценарий оболочки что-либо еще, кроме присвоения переменных?

В зависимости отответы на эти, варианты различной сложности существуют.

Спасибо за разъяснения.Хорошо, вот как это сделать.Помимо присвоения переменных, ваш скрипт не имеет побочных эффектов.Это позволяет запускать скрипт изнутри perl.Как мы узнаем, какие переменные экспортируются в сценарий?Мы могли бы попытаться разобрать сценарий оболочки, но это не способ Unix использовать инструменты, которые хорошо выполняют одну вещь и объединяют их в цепочку.Вместо этого мы используем команду оболочки export -p, чтобы она объявляла все экспортируемые переменные и их значения.Чтобы найти только переменные, фактически установленные скриптом, а не весь другой шум, скрипт запускается с чистой средой с использованием env -i, еще одного недооцененного драгоценного камня POSIX.

Все вместе:

#!/usr/bin/env perl
use strict;
use warnings;

my @cmd = (
  "env", "-i", "PATH=$ENV{PATH}", "sh", "-c", ". ./myshell.sh; export -p"
);

open (my $SCRIPT, '-|', @cmd) or die;
while (<$SCRIPT>) {
    next unless /^export ([^=]*)=(.*)/;
    print "\$ENV{$1} = '$2'\n";
    $ENV{$1} = $2;
}
close $SCRIPT;

Примечания:

  • Вам необходимо перейти на env -i всю среду, в которой нуждается myshell.sh, например, PATH.
  • Снаряды обычно экспортируют переменную PWD;если вы не хотите этого в своем хэше perl ENV, добавьте next if $1 eq 'PWD'; после первого next.

Это должно сработать.Дайте мне знать, если это работает.

Смотрите также:

1 голос
/ 10 апреля 2011

Попробуйте Shell :: Source .

0 голосов
/ 23 июня 2017

Теперь это можно сделать с помощью Env::Modify с небольшими изменениями существующего кода.

use Env::Modify 'system';
...
system("sh myshell.sh");
print $ENV{MYROOTDIR};      # "/home/myuser/mytools"

или, если все, что делает ваш сценарий оболочки, изменяет среду, вы можете использовать функцию source

use Env::Modify `source`;
source("myshell.sh");
print $ENV{MYVERSION};      # "0.4a"
0 голосов
/ 11 апреля 2011

Не проще ли сценарию оболочки установить переменные и затем вызвать perl-программу?

т.е:.

run.sh:

#!/bin/sh

export MYROOTDIR=/home/myuser/mytools
export PATH=$MYROOTDIR/bin:$PATH
export MYVERSION=0.4a

./program.pl
0 голосов
/ 10 апреля 2011

Вы можете установить переменные среды внутри блока BEGIN. Блок BEGIN выполняется до остальной части кода, установка переменных окружения в этом блоке делает их видимыми для остальной части кода до его компиляции и запуска. Если у вас есть какие-либо модули perl для «использования» в зависимости от настроек среды, блок BEGIN делает это возможным.

Perl использует специальный хеш% ENV для поддержки переменных среды. Вы можете изменить содержимое этого хеша для установки переменных env.

ПРИМЕР:

BEGIN 
{
    $ENV { 'MYROOTDIR' } = '/home/myuser/mytools';
    $ENV { 'PATH' } = "$ENV{ 'MYROOTDIR' }/bin:$ENV{ 'PATH' }";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...