Home > Software engineering >  Process “aws ecs list-tasks” JSON output with “aws ecs execute-command”?
Process “aws ecs list-tasks” JSON output with “aws ecs execute-command”?

Time:08-24

For example do this command.

aws ecs list-tasks --cluster aic-prod

then it returns below

{
    "taskArns": [
        "arn:aws:ecs:ap-northeast-1:678100228133:task/aic-prod-cn/ae340032378f4155bd2d0eb4ee60b5c7"
    ]
}

then do next command using the ae340032378f4155bd2d0eb4ee60b5c7 of return sentence.

aws ecs execute-command --cluster aic-prod-cn --container AicDjangoContainer --interactive --command '/bin/bash' --task ae340032378f4155bd2d0eb4ee60b5c7

I want to do this thing in one sentence, or shell script. Is it possible?

I googled around the regular expression, but still unclear.

 aws ecs list-tasks --cluster aic-prod | grep taskArns | (regular expression??)

Could you give some help?

CodePudding user response:

Manipulate JSON with jq

jq is the best tool for manipulating JSON in shell scripts. It has a pretty sophisticated query language.

Here's how you could use it to extract the string you need. I've shown the query I've built piece by piece so you can see the what's happening a step at a time:

❯ aws ecs list-tasks --cluster aic-prod | jq
{
  "taskArns": [
    "arn:aws:ecs:ap-northeast-1:678100228133:task/aic-prod-cn/ae340032378f4155bd2d0eb4ee60b5c7"
  ]
}

❯ aws ecs list-tasks --cluster aic-prod | jq '.taskArns[0]'
"arn:aws:ecs:ap-northeast-1:678100228133:task/aic-prod-cn/ae340032378f4155bd2d0eb4ee60b5c7"

❯ aws ecs list-tasks --cluster aic-prod | jq '.taskArns[0] | split(":")[-1]'
"task/aic-prod-cn/ae340032378f4155bd2d0eb4ee60b5c7"

❯ aws ecs list-tasks --cluster aic-prod | jq '.taskArns[0] | split(":")[-1] | split("/")[-1]'
"ae340032378f4155bd2d0eb4ee60b5c7"

Capture output with $(...)

The next step is to add -r so it prints the string raw without quotes, and use $(...) to capture the output so we can reuse it in a second command.

task_id=$(aws ecs list-tasks --cluster aic-prod | jq -r '.taskArns[0] | split(":")[-1] | split("/")[-1]')
aws ecs execute-command --cluster aic-prod-cn --container AicDjangoContainer --interactive --command '/bin/bash' --task "$task_id"

Or use xargs

Another way to write this is with xargs, which takes the output of one command and passes it as an argument to the next.

aws ecs list-tasks --cluster aic-prod |
    jq -r '.taskArns[0] | split(":")[-1] | split("/")[-1]' |
    xargs aws ecs execute-command --cluster aic-prod-cn --container AicDjangoContainer --interactive --command '/bin/bash' --task
  • Related