Perl调用curl时用变量传递JSON数据异常的解决方法问询
三种curl执行逻辑差异与Perl传参解决方案
三者执行逻辑差异
$curl_out_1:JSON字符串硬编码,--data后的参数外层有单引号包裹,shell执行时不会解析JSON内部的双引号,报文结构完整,可正常请求。$curl_out_2:Perl拼接的JSON直接嵌入反引号命令,最终生成的shell命令中JSON没有外层引号保护,shell会把JSON内的双引号识别为参数分隔符,拆分报文导致结构损坏。$curl_out_3:JSON存入Perl变量后传入命令,和第二种情况逻辑一致,shell解析时会破坏JSON双引号结构,报文错误导致服务端返回异常。
最优解决方案
核心是避免shell解析破坏JSON结构,有两种可选方案:
快速修复(适配现有代码)
对变量内容做单引号转义后,给变量外层套单引号传入命令即可让第三行正常运行:
my $tsFormatted = '2021-06-10'; my $metaLoad = '{"validDate": "'.$tsFormatted.'"}'; # 新增转义逻辑 $metaLoad =~ s/'/'\\''/g; my $curl_out_3 = `curl -s -X POST -H 'Content-Type: application/json' $mw_meta_load_api --key $mw_access_key --cert $mw_access_cert --data '$metaLoad'`;
生产环境推荐方案
使用String::ShellQuote模块处理参数转义,同时用JSON模块生成JSON避免手动拼接出错,彻底规避shell注入和报文损坏问题:
use String::ShellQuote qw(shell_quote); use JSON qw(encode_json); my $tsFormatted = '2021-06-10'; my $metaLoad = encode_json({ validDate => $tsFormatted }); my @curl_params = ( 'curl', '-s', '-X', 'POST', '-H', 'Content-Type: application/json', $mw_meta_load_api, '--key', $mw_access_key, '--cert', $mw_access_cert, '--data', $metaLoad ); my $curl_cmd = shell_quote(@curl_params); my $curl_out_3 = `$curl_cmd`;
提示:更建议直接使用Perl原生HTTP客户端(如LWP::UserAgent、Mojo::UserAgent)发请求,完全绕开shell解析环节,安全性和性能都优于调用外部curl命令。
内容的提问来源于stack exchange,提问作者SachinJose
相关产品推荐
相关产品推荐

