繁体   English   中英

为什么exec()默默地丢弃字节?

[英]Why is exec() silently discarding bytes?

经过大量的挣扎,我发现了一些我无法解释/解决的行为,所以在这里寻求帮助。 在我们的服务器( Ubuntu 16.04.5 LTS,PHP 7.0.30 )上,我们使用'httpdocs'之外的一些工具,使用exec()调用它们来获取它们的输出。 在这种情况下,它是QRCode生成器。

但是,某些QR码将不会显示。 我们从工具中获得了一个输出( 输出PNG的数据 ),但当我们将其显示为图像时,它似乎因某种原因而被破坏。

经过大量的调试后我发现结果有时与工具的输出相差1或2个字节。

我使用下面的QR码( 12345 )进行了上次调试,这是一个240字节的文件。 但是,最终输出时,长度似乎是239字节,所以我们在某处丢失了一个字节?

QR码示例

我发现使用exec() ,我们正在创建一个输出数组。 尾随空格(如\\ n)不包含在此数组中,因此implode()将数组粘贴回字符串,如下所示:

<?php

$cmd = 'cat qr.png';
$output = array();
$exit_code = 0;

exec($cmd, $output, $exit_code);

if($exit_code === 0)
{
    header ("Content-type: image/png;");
    print implode(PHP_EOL, $output);
}
die();

但由于某种原因,在这个过程中丢失了一个字节? 我已经使用shell_exec()尝试了一些其他解决方案( 但这里没有return_var,所以我们无法检查验证进程......

<?php

$command = 'cat qr.png';

$output = shell_exec($command);
if($output !== null)
{
    header ("Content-type: image/png;");
    print $output;
}
die();

...并使用passthru()但这会直接输出内容,这是不希望的。输出缓冲在下面的示例中是不可能的,在实际代码中......

<?php

$command = 'cat qr.png';
$return_var = 0;

ob_start();
passthru($command, $return_var);

if($return_var === 0)
{
    header ("Content-type: image/png;");
    $output = ob_get_clean();
    print $output;
}
die();

到目前为止, exec()函数总是对我们很好,导致$ return_var $输出,但现在我丢失了字节。 我已经尝试了PHP_EOL的一些变体,我们现在使用胶水( \\ n,\\ r和\\ n \\ r ),但是前两个行结尾,我仍然只有239个字节和最后一个,我最终得到241个字节,所以1个字节到很多。

为什么我在这里输掉一个字节? 将$ output-array转换回字符串的正确方法是什么? 有没有办法通过破坏阵列来恢复240字节的输出? 或者还有其他功能我还没有找到执行命令,它会给我输出以及return_var?

根据exec的手动输入,该函数返回最后一行输出。 最后一行是否也包含在$output的最后一个元素中尚不清楚。

但更重要的是手册说明:

尾随空格(例如\\ n)不包含在此数组中。

我猜这是数组的每个元素(即输出的每行),但无论哪种方式,你的空白在这里都很重要,因为你没有处理文本 - 所有的字节都很重要而且有意义。 请记住,空白并不仅仅意味着\\n 它也可以意味着\\t (例如,一个空格)。

如果一行以F\\t\\n结尾(大写字母F或任何其他非空白字符,制表符,然后是换行符),则两个空格字符都将从末尾删除。 在进行内implode操作时,你可能会把\\n放回去,但你永远不会知道被剥离的\\t

这里要实现的关键是exec期望处理纯文本而不是原始二进制数据

我建议不要使用cat qr.png ,而是使用base64 qr.png将二进制数据编码为ASCII字符串,然后使用base64_decode在PHP中base64_decode进行解码。 如果您不打算在现实中使用cat ,您仍然可以通过base64 QR生成命令的输出,如下所示: generate-qr-png |base64 在那种情况下不应该有任何重要的空白,所以没有任何东西会被exec吸引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM