Итак, для начала, я не уверен, что ваш config.pl
действительно правильный подход - это не perl
для начала, потому что он не компилируется. В любом случае, попытка оценить материал для «анализа конфигурации» в целом не является хорошим планом — он довольно подвержен неприятным сбоям и недостаткам безопасности, поэтому его следует зарезервировать на тот случай, когда это необходимо.
Я бы призвал вас сделать это по-другому:
Запишите его как модуль
Что-то вроде этого:
package MyConfig;
# Configuration file for main script
our %config = (
username => "username",
password => "none_of_your_business",
favorite_color => "0x0000FF",
);
Затем вы можете в своем основном скрипте:
use MyConfig; #note - the file needs to be the same name, and in @INC
и получить к нему доступ как:
print $MyConfig::config{username},"\n";
Если вы не можете поместить его в существующий @INC
— по каким-то причинам вы не можете этого сделать, FindBin
позволяет вам использовать пути относительно местоположения вашего скрипта:
use FindBin;
use lib "$FindBin::Bin";
use MyConfig;
Напишите свою «конфигурацию» в виде определенного парсируемого формата, а не исполняемого кода.
YAML
YAML
очень хорошо подходит для файла конфигурации, в частности:
use YAML::XS;
open ( my $config_file, '<', 'config.yml' ) or die $!;
my $config = Load ( do { local $/; <$config_file> });
print $config -> {username};
И ваш файл конфигурации выглядит так:
username: "username"
password: "password_here"
favourite_color: "green"
air_speed_of_unladen_swallow: "african_or_european?"
(YAML также поддерживает многомерные структуры данных, массивы и т. д. Однако вам это не нужно.)
JSON
JSON
выглядит почти так же, только ввод:
{
"username": "username",
"password": "password_here",
"favourite_color": "green",
"air_speed_of_unladen_swallow": "african_or_european?"
}
Вы читаете его с:
use JSON;
open ( my $config_file, '<', 'config.json' ) or die $!;
my $config = from_json ( do { local $/; <$config_file> });
Использование относительных путей к конфигу:
Вам вообще не нужно беспокоиться о @INC
. Вы можете просто использовать на основе относительного пути... но лучше НЕ делать этого, а вместо этого использовать FindBin
, что позволяет указать «относительно моего пути к сценарию», и это намного надежнее.
use FindBin;
open ( my $config_file, '<', "$FindBin::Bin/config.yml" ) or die $!;
И тогда вы будете знать, что читаете тот, который находится в том же каталоге, что и ваш скрипт, независимо от того, откуда он вызывается.
конкретные вопросы:
С чьей точки зрения это "./": бинарный файл Perl, исполняемый сценарий Perl, CWD из оболочки пользователя или что-то еще?
Текущий рабочий каталог проходит через процессы. Таким образом, оболочка пользователя по умолчанию, если скрипт perl не выполняет chdir
Существуют ли риски безопасности, о которых следует знать?
Каждый раз, когда вы «оцениваете» что-то, как если бы это был исполняемый код (и EXPR
может быть таковым), существует риск безопасности. Это, вероятно, не так много, потому что скрипт будет работать от имени пользователя, а пользователь — это человек, который может вмешиваться в CWD
. К основным рискам относятся:
- user is in a 'different' directory where someone else has put a malicious thing for them to run. (e.g. imagine of 'config.pl' had
rm -rf /*
in it for example). Maybe there's a 'config.pl' in /tmp
that they 'run' accidentally?
- The thing you're
eval
ing has a typo, and breaks the script in funky and unexpected ways. (E.g. maybe it redefines $[
and messes with program logic henceforth in ways that are hard to debug)
- script делает что-либо в привилегированном контексте. Это не так, но посмотрите предыдущий пункт и представьте, если вы
root
или другой привилегированный пользователь.
Это лучше или хуже, чем изменение @INC и просто использование базового имени файла?
Имхо хуже. На самом деле просто не изменяйте @INC
вообще и используйте полный путь или относительный, используя FindBin
. И не делай eval
вещей, когда в этом нет необходимости.
person
Sobrique
schedule
12.04.2018
do './stat.pl'
во многом похоже наeval `cat stat.pl`;
- person ikegami   schedule 12.04.2018.
ссылается CWD. - person ikegami   schedule 12.04.2018