如何获取 boto3 ecsexecute_command 的输出?

The*_*erk 10 amazon-web-services amazon-ecs boto3 aws-ssm

我有一个在 Fargate 上运行的 ECS 任务,我想在 boto3 中运行命令并获取输出。我可以在 awscli 中很好地做到这一点。

\n
\xe2\x9e\x9c aws ecs execute-command --cluster cluster1 \\                                                                                   \n    --task abc \\\n    --container container1 \\\n    --interactive \\\n    --command \'echo hi\'    \n\nThe Session Manager plugin was installed successfully. Use the AWS CLI to start a session.\n\nStarting session with SessionId: ecs-execute-command-0f913e47ae7801aeb\nhi\n\nExiting session with sessionId: ecs-execute-command-0f913e47ae7801aeb.\n
Run Code Online (Sandbox Code Playgroud)\n

但我无法弄清楚如何在 boto3 中获得相同的输出。

\n
\xe2\x9e\x9c aws ecs execute-command --cluster cluster1 \\                                                                                   \n    --task abc \\\n    --container container1 \\\n    --interactive \\\n    --command \'echo hi\'    \n\nThe Session Manager plugin was installed successfully. Use the AWS CLI to start a session.\n\nStarting session with SessionId: ecs-execute-command-0f913e47ae7801aeb\nhi\n\nExiting session with sessionId: ecs-execute-command-0f913e47ae7801aeb.\n
Run Code Online (Sandbox Code Playgroud)\n

现在会话正在终止,我收到了另一个文档,但似乎仍然没有输出到任何地方。有人从中得到输出吗?如何?

\n
\n

对于寻求类似解决方案的任何人,我创建了一个工具来简化此任务。它被称为闯入者。这主要归功于Andrey 的出色回答

\n

And*_*rey 11

好的,基本上通过阅读 ssm 会话管理器插件源代码,我想出了以下简化的重新实现,它能够仅获取命令输出:(您需要pip install websocket-client construct

import json
import uuid

import boto3
import construct as c
import websocket

ecs = boto3.client("ecs")
ssm = boto3.client("ssm")
exec_resp = ecs.execute_command(
    cluster=self.cluster,
    task=self.task,
    container=self.container,
    interactive=True,
    command="ls -la /",
)

session = exec_resp['session']
connection = websocket.create_connection(session['streamUrl'])
try:
    init_payload = {
        "MessageSchemaVersion": "1.0",
        "RequestId": str(uuid.uuid4()),
        "TokenValue": session['tokenValue']
    }
    connection.send(json.dumps(init_payload))

    AgentMessageHeader = c.Struct(
        'HeaderLength' / c.Int32ub,
        'MessageType' / c.PaddedString(32, 'ascii'),
    )

    AgentMessagePayload = c.Struct(
        'PayloadLength' / c.Int32ub,
        'Payload' / c.PaddedString(c.this.PayloadLength, 'ascii')
    )

    while True:
        response = connection.recv()

        message = AgentMessageHeader.parse(response)

        if 'channel_closed' in message.MessageType:
            raise Exception('Channel closed before command output was received')

        if 'output_stream_data' in message.MessageType:
            break

finally:
    connection.close()

payload_message = AgentMessagePayload.parse(response[message.HeaderLength:])

print(payload_message.Payload)
Run Code Online (Sandbox Code Playgroud)