Использование переменных окружения 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 и
Использование системных команд в Perl вместо встроенных библиотек / функций [дубликат]
для трезвого и подробного изложения преимуществ.
В случае, если вам нужно запустить внешние команды, лучше всего избегать оболочки, например, используя систему с несколькими аргументами системы. Если вам также нужен вывод команды, в Perl есть различные модули, которые это обеспечивают. Смотрите ссылки ниже.
Если вам также нужно использовать возможности оболочки, вместо того, чтобы указывать все правильно, чтобы оболочка получила то, что ей нужно, лучше используйте готовый инструмент, такой как String:: ShellQuote.
Некоторые примеры:
Как использовать обе трубы и предотвратить расширение оболочки в системной функции perl?
Perl рассматривает '<' как обычный символ, а не как перенаправление вывода
Как передать содержимое переменной как STDIN в операторе qx{} в Perl?
Системная команда Perl с выводом нескольких параметров в файл.
Обратите внимание, что оператор 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
,
Обратите внимание, что с помощью символической ссылки вы не можете передать каталог вместо имени ссылки. Смотрите эту страницу.