我试图使用系统curl将gzip压缩数据发布到服务器但我最终会遇到奇怪的错误
`curl -sS -X POST -H "Content-Type: application/gzip" --data-binary $data $url`
给出
curl: no URL specified!
和
`curl -sS -X POST -H "Content-Type: application/gzip" --data-binary "$data" $url`
给出
sh: -c: line 0: unexpected EOF while looking for matching `"'
sh: -c: line 1: syntax error: unexpected end of file
答案 0 :(得分:4)
添加"
是朝着正确方向迈出的一步,但您并未认为$data
可能包含"
,$
等。您可以使用{ {3}}解决这个问题。
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote(
curl => (
'-sS',
'-X' => 'POST',
'-H' => 'Content-Type: application/gzip',
'--data-binary' => $data,
$url,
),
);
my $output = `$cmd`;
或者你可以完全避开外壳。
my @cmd = (
curl => (
'-sS',
'-X' => 'POST',
'-H' => 'Content-Type: application/gzip',
'--data-binary' => $data,
$url,
),
);
open(my $pipe, '-|', @cmd) or die $!;
my $output = do { local $/; <$pipe> };
close($pipe);
或者,如果您实际上不需要捕获输出,则以下内容也完全避免了shell:
system(
curl => (
'-sS',
'-X' => 'POST',
'-H' => 'Content-Type: application/gzip',
'--data-binary' => $data,
$url,
),
);
那就是说,我看不出你怎么可能发送包含NUL字节的字符串,这可能是一个gzip压缩文件。我认为你的方法存在固有的缺陷。
您是否知道可以通过String::ShellQuote访问libcurl
(curl
的胆量)?
答案 1 :(得分:3)
我没有成功地让curl直接从stdin读取数据,但是进程替换确实有效,例如:
curl -sS -X POST -H "Content-Type: application/gzip" --data-binary @<(echo "Uncompressed data" | gzip) $url
此技术不再需要首先写入临时文件。
答案 2 :(得分:0)
这是因为您的二进制数据包含所有类型的垃圾,包括引号和空字节,这会混淆shell。尝试将您的数据放入某个文件并发布该文件。