Использование переменных окружения Bash из скрипта Perl?

Я пытаюсь запустить команду Bash из моей Perl-программы. Однако Perl, похоже, путает мою переменную окружения Bash $PWD как переменную Perl.

Как я могу сделать это просто прочитать все это как строку?

Это то, что я пытаюсь запустить

my $path = /first/path;
`ln -s $path $PWD/second/path`

Эти галочки запускает вторую строку в Bash. Использование System() создает ту же проблему.

Есть идеи?

1 ответ

Решение

Здесь есть два запроса на использование переменных Bash и выполнение внешних команд.

Здесь %ENV хеш в Perl, с переменными окружения

perl -wE'say $ENV{PWD}'

Однако зачастую лучше получить эквивалент в скрипте, так как вещи могут иметь слегка другое значение для скрипта или измениться во время работы скрипта.

Что еще более важно, использование команд оболочки открывает вам все возможные проблемы с цитированием, внедрением оболочки и интерпретацией. Например, указанная вами команда опасна, как указано в комментарии Charles Duffy. В принципе лучше использовать богатый функционал Perl. Смотри например

для трезвого и подробного изложения преимуществ.


В случае, если вам нужно запустить внешние команды, лучше всего избегать оболочки, например, используя систему с несколькими аргументами системы. Если вам также нужен вывод команды, в Perl есть различные модули, которые это обеспечивают. Смотрите ссылки ниже.

Если вам также нужно использовать возможности оболочки, вместо того, чтобы указывать все правильно, чтобы оболочка получила то, что ей нужно, лучше используйте готовый инструмент, такой как String:: ShellQuote.

Некоторые примеры:

Обратите внимание, что оператор qx (backticks) использует /bin/sh, которые могут или не могут быть отправлены в Bash. Так что если вы хотите Bash, вам понадобится system('/bin/bash', '-c', @cmd), Смотрите ссылки с примерами.


Вот полный пример, связанный с целью вопроса.

Рабочий каталог вашей программы может отличаться от ожидаемого в зависимости от того, как он запущен. Для одного это меняется после chdir, Я не знаю вашего точного намерения с PWD, но есть ядро Cwd::cwdи FindBin::$RealBin в перл.

Создать символическую ссылку на $pathс относительным путем, следующим за текущим рабочим каталогом

use warnings;
use strict;
use Cwd qw(cwd);

my $cwd = cwd;

my $path = '/first/path';

symlink($path, "$cwd/second/path") or die "Can't make a symlink: $!";

Если путь предназначен для определения местоположения скрипта, используйте FindBin::$RealBin вместо cwd,

Обратите внимание, что с помощью символической ссылки вы не можете передать каталог вместо имени ссылки. Смотрите эту страницу.

Другие вопросы по тегам