0

当运行一个

http://127.0.0.1:2375/exec/xxxxx/start

我得到一个类型的响应,响应中application/vnd.docker.raw-stream 有一些二进制字符。例如,当在 docker 容器中调用“date”时,响应总是如下所示(来自邮递员的屏幕截图):

在此处输入图像描述

在 joe(编辑)我看到:A@@@@@@]Wed Dec 29 00:55:05 CET 2021
和 vi(编辑)显示A^@^@^@^@^@^@^]Wed Dec 29 00:55:05 CET 2021

我找不到任何东西来通过 docker 控制输出。所以我想问,摆脱这些二进制字符的最好方法是什么?最后,我想通过 PHP 解析结果,但也许有办法一开始就避免这些字符,因为这些字符几乎无处不在。

4

1 回答 1

0

第一的:

据我所知,除了“流”之外,没有办法告诉 Docker 引擎获取其他内容作为响应,因为这是某些 Docker 调用的本质,例如,如果您“附加”到运行容器,输出可以是无限的,所以它不是“一次调用->等待 2 秒->获得响应”——因为容器可以永远运行,所以输出可以是无限长的。

第二:

使用简单的正则表达式删除二进制字符串的工作方式与此处解释的一样。

最后:

如何用 PHP 读取 Stream?

在大多数情况下,使用 Guzzle 是使用 PHP 处理 HTTP 调用的最简单方法。

<?php
$response = $client->request('POST', '/exec/' . $id . '/start', [
    'json' => [
        "Detach" => false,
        "Tty"    => false,
    ],
    'stream' => true // <---------- THIS IS THE IMPORTANT PART HERE
]);

Docker 引擎文档清楚地解释了如何读取 Stream:

实现此协议的最简单方法如下:

  1. 读取 8 个字节。
  2. 根据第一个字节选择标准输出或标准错误。
  3. 从最后四个字节中提取帧大小。
  4. 读取提取的大小并将其输出到正确的输出上。
  5. 转到 1。

所以在一个旧的 PHP Package的帮助下,它显示了它是如何完成的,我终于能够得到一个“清晰”的输出:

$body = $response->getBody();

$str = '';
do {
    $strToUnpack = $body->read(8);
    if (strlen($strToUnpack)) {
        $decoded = \unpack('C1type/C3/N1size', $strToUnpack);
        if ($decoded) {
            $str = $body->read($decoded['size']);
            echo $str . "\n";
        }
    }
} while (!$body->of());
于 2021-12-31T17:08:21.900 回答