Perl-插入JSON字符串值

Perl-插入JSON字符串值,json,perl,Json,Perl,我有一个json文件,如下所示: "tool_name": { "command": "$ENV{TOOL_BIN_DIR}/some_file_name", "args": "some args" } my $cmd = "$data->{tool_name}->{command}"; print $cmd; 我正在使用Perl5.14中的use:JSON。使用decode_json函数读取文件并将数据放入perl哈希 但是,当我引用以下代码时,从如下代码中读取

我有一个json文件,如下所示:

"tool_name": {
    "command": "$ENV{TOOL_BIN_DIR}/some_file_name",
    "args": "some args"
}
my $cmd = "$data->{tool_name}->{command}";
print $cmd;
我正在使用Perl5.14中的
use:JSON
。使用
decode_json
函数读取文件并将数据放入perl哈希

但是,当我引用以下代码时,从如下代码中读取数据:

"tool_name": {
    "command": "$ENV{TOOL_BIN_DIR}/some_file_name",
    "args": "some args"
}
my $cmd = "$data->{tool_name}->{command}";
print $cmd;
我明白了

如何让perl解析这个变量的值


本例使用Environment变量,但一般来说,如果我想使用JSON中的变量,我该怎么做呢?

您可以使用eval,如:

my $cmd = '$ENV{HOME}/toto';
print eval('"' . $cmd . '"'), "\n";

但请记住,从安全角度来看,这是非常不安全的。您可能应该避免这样做。

使用
eval
会导致恶意或意外损坏:您正在执行的字符串可能包含任何可能对系统产生任何影响的Perl代码

最好使用模块中的
interpolate
,该模块使用Perl自己的插值引擎,在运行时扩展普通双引号字符串

此程序为环境变量
TOOL\u BIN\u DIR
设置一个值,并展开
TOOL\u name
散列中包含美元
$
或在
@
符号处的所有值

我使用了
Data::Dump
来显示插值后的数据内容

如果不知道哪些值可能包含需要展开的值,则可能需要编写一个递归子例程来处理所有嵌套哈希和数组的值

use strict;
use warnings 'all';

use JSON 'decode_json';
use String::Interpolate 'interpolate';
use Data::Dump 'dd';

my $data = decode_json <<'__END_JSON__';
{
    "tool_name": {
        "command": "$ENV{TOOL_BIN_DIR}/some_file_name",
        "args": "some args"
    }
}
__END_JSON__

$ENV{TOOL_BIN_DIR} = 'tool_dir_test';

for ( values %{ $data->{tool_name} } ) {
    $_ = interpolate($_) if /[\$\@]/;
}

dd $data;

您的文件应该是某种配置文件吗?除了环境变量的字符串插值外,您还需要支持其他Perl语法吗?您遇到了什么问题?你的密码在哪里?你要我们为你写一个模板处理器吗?@ThisSuiteisBlack不是的,这是一个配置文件。不,我就这些need@ikegami:不,我只是问是否有办法将JSON中存储的perl字符串插入为strings,即“perl字符串”是什么?你是说Perl字符串文字<代码>$ENV{TOOL\u BIN\u DIR}/some\u file\u name不是有效的Perl、字符串或其他形式。如果您确实有有效的Perl,那么可以执行它,是的。不过,将Perl代码存储在配置文件中确实是“不明智的”。相反,您有一个自定义模板语言。因此,您将需要一个自定义模板解析器和处理器。你应该使用现有的模板语言。谢谢。我会试试这个。更好的方法是直接插值。@Deadman这是最直接的方法。你所拥有的只是一根绳子;您需要以某种方式告诉perl将字符串解析为perl代码并执行它,这正是string
eval
所做的。非常感谢@ThisSuitesBlackNot这太糟糕了!如果字符串包含
,则失败。还有一个问题:
perl-e'CORE::say eval(q{}.$ARGV[0].q{})'${print qq{我刚刚删除了所有文件\n};\qq{x}“
。不要执行配置文件!对否决我的人只需说两句话:module String::Interpolate包含对eval函数的调用,perl interpolation已经可以用来删除所有文件。我想我的警告已经够清楚了。Re”使用perl自己的插值引擎”“太可怕了
perl-MString::Interpolate=Interpolate-e'CORE::say Interpolate($ARGV[0])'${print“我刚刚删除了你所有的文件\n”;\“x”}
。不要执行配置文件!还有
safe\u interpolate
,但这仍然会留下足够的操作码来进行DOS攻击。最好不要执行任何事情。