2010-09-09 3 views
2

можно ли запустить сценарий оболочки в Perl-скрипте?Можем ли мы исправить сценарий оболочки в perl-скрипте

Пример: Программа 1:

cat test1.sh 
#!/bin/ksh 
DATE=/bin/date 

Программа 2:

cat test2.sh 
#!/bin/ksh 
. ./test1.sh 
echo `$DATE` 

Программа 3:

cat test3.pl 
#!/usr/bin/perl 
### here I need to source the test1.sh script 
print `$DATE`' 

Как источник оболочки в Perl, чтобы получить дату распечатывается, когда Я выполняю test3.pl

благодаря Raghu

+0

любая причина, по которой вы не хотите использовать модули времени даты Perl для этого? – ghostdog74

+1

@ ghostdog74 Вам даже не нужен модуль. Функция «localtime» в скалярном контексте создает почти идентичную строку: 'perl -le 'print scalar localtime'', вам просто нужно получить часовой пояс, и они будут одинаковыми. –

+0

Эй, да, это всего лишь пример ... это может быть любая вещь вместо даты (ls, chown, echo .....), какая команда может быть в первом файле, мне нужно передать perl ; – raghu

ответ

3

Вы не можете сделать

system("source src.sh"); 

system() начинает новую подоболочку, ваши переменные окружения не получают переданы оболочки сценарий Perl работает. Даже если ваш скрипт экспортирует переменные, он будет экспортировать их в под-оболочку, а не в вашу реальную оболочку.

Одно решение было бы написать сценарий оболочки, который

  1. Первые источники сценарий оболочки, а затем
  2. Запускает сценарий PERL
+1

Это то, что я обычно делаю, но он не работает, если вы хотите использовать разные файлы в зависимости от того, что вы делаете. Например, скажем, у вас есть три базы данных и для доступа к ним нужны разные среды. Вы заранее не знаете, к какой базе данных вам нужно подключиться. В таких случаях метод обертывания падает. –

+1

@ Час. Оуэнс: Ты прав. – codaddict

0

Вы можете файлы не источник оболочки в Perl 5 Sourcing буквально запускает команды в файле оболочки в целевой оболочке; однако, тривиально открыть и прочитать файл:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Carp; 

sub source { 
    my $file = shift; 
    open my $fh, "<", $file 
     or croak "could not open $file: $!"; 

    while (<$fh>) { 
     chomp; 
     #FIXME: this regex isn't quite good enough 
     next unless my ($var, $value) = /\s*(\w+)=([^#]+)/; 
     $ENV{$var} = $value; 
    } 
} 

source "./test1.sh"; 

print "$ENV{DATE}\n"; 
0

Uhm .. является следующим обманом?

#!/bin/sh 
. ./test1.sh # source the test script 
echo Bash says $DATE 
export DATE;  # KEY to have the below Perl bit see $ENV{DATE} 
perl <<'ENDPERL'; 
    print "Perl says $ENV{DATE}\n"; 
ENDPERL 

Проблема заключается в том, что снабжает файл ш может делать что угодно, а не просто присвоить значение переменной X Y ...

0

Я не знаю, что это поможет, но я был вынужден придумайте способ написать это в Perl. Мое намерение заключалось в том, чтобы Perl запускал сценарий оболочки и назначал любые переменные оболочки, которые он задает в именах переменных в скрипте Perl.

Другие верны в том, что любой сценарий оболочки, который вы «источник», будет находиться в суб-оболочке. Я решил, что могу использовать «sh -x cmd», чтобы по крайней мере иметь оболочку, отображающую переменные по мере их установки.

Вот что я написал:

use strict; use warnings; 

our $DATE; 

my $sh_script = "./test1.sh"; 

my $fh; 
open($fh, "sh -x '$sh_script' 2>&1 1>/dev/null |") or die "open: $!"; 
foreach my $line (<$fh>) { 
    my ($name, $val); 
    if ($line =~ /^\+ (\w+)='(.+)'$/) { # Parse "+ DATE='/bin/date;' 
     $name = $1; 
     ($val = $2) =~ s{'\\''}{'}g; # handle escaped single-quotes (eg. "+ VAR='one'\''two'") 
    } elsif ($line =~ /^\+ (\w+)=(\S+)$/) { # Parse "+ DATE=/bin/date" 
     $name = $1; 
     $val = $2; 
    } else { 
     next; 
    } 
    print "Setting '$name' to '$val'\n" if (1); 
    # NOTE: It'd be better to use something like "$shell_vars{$name} = $val", 
    # but this does what was asked (ie. $DATE = "/bin/date")... 
    no strict 'refs'; 
    ${$name} = $val; # assign to like-named variable in Perl 
} 
close($fh) or die "close: ", $! ? $! : "Exit status $?"; 

print "DATE: ", `$DATE` if defined($DATE); 

Там, конечно, более проверки ошибок вы могли бы сделать, но это сделал трюк для меня, если все, что вы хотите, чтобы поймать это переменные оболочки.

1

Вы можете сделать что-то простое, как это:

system "source /path/to/shell_env.sh &&" 
    . "/path/to/script.sh"; 

Обратите внимание, что это отличается от следующего, не рекомендуется:

system "source /path/to/shell_env.sh &&" 
     . "/bin/sh /path/to/script.sh"; 
0

Да, теперь вы можете сделать это с Env::Modify module ,

use Env::Modify qw(:ksh source); 
source("./test1.sh");  # env settings from test1.sh now available in Perl 
print `$ENV{DATE}`;  # print `/bin/date`; 
Смежные вопросы