TravelingLex
TravelingLex

Reputation: 477

Reading several variables from a single command's multi-line output

I'm running into an issue with the read command. I'm trying to get read to run through the output of my awscli command to extract VPC_ID, VPC_CIDR and VPC_NAME. Unfortunately its no longer working since upgrading to bash 5.0.

Here is the following code: read VPC_ID VPC_CIDR VPC_NAME <<<$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=${AWS_PROFILE}-vpc" --output json | jq -r '.Vpcs[] | .VpcId,.CidrBlock, (.Tags[]|select(.Key=="Name")|.Value)')

When I run aws ec2 describe-vpcs --filters "Name=tag:Name,Values=${AWS_PROFILE}-vpc" --output json | jq -r '.Vpcs[] | .VpcId,.CidrBlock, (.Tags[]|select(.Key=="Name")|.Value)'

I get my expected output but when I attached the read command in front of it, I'm only able to assign the first variable none of the other ones...

Upvotes: 0

Views: 464

Answers (2)

Glenn Slaven
Glenn Slaven

Reputation: 34213

With modern bash and the AWS CLI v2 you can simplify this and you don't need jq.

read -r VPC_ID VPC_CIDR VPC_NAME< <(aws ec2 describe-vpcs \
  --filters "Name=tag:Name,Values=${AWS_PROFILE}-vpc"  \
  --query "Vpcs[*].[VpcId,CidrBlock,Tags[?Key == 'Name']|[0].Value]" \
  --output text)

Upvotes: 0

Charles Duffy
Charles Duffy

Reputation: 295619

The problem is that read, by default, stops at the first newline it sees. (This can be overridden with the -d argument). You can work around this by running a separate read per variable, or running read with a different character used as the record delimiter.

The first approach:

{ read -r VPC_ID && read -r VPC_CIDR && read -r VPC_NAME; } < <(
  aws ec2 describe-vpcs --filters "Name=tag:Name,Values=${AWS_PROFILE}-vpc" --output json \
  | jq -r '.Vpcs[] | .VpcId,.CidrBlock, (.Tags[]|select(.Key=="Name")|.Value)'
)

The second approach, which adds a printf '\0' when the inner command is successful, which read -d '' recognizes to mean the record is complete:

IFS=$'\n' read -r -d '' VPC_ID VPC_CIDR VPC_NAME < <(
  aws ec2 describe-vpcs --filters "Name=tag:Name,Values=${AWS_PROFILE}-vpc" --output json \
  | jq -r '.Vpcs[] | .VpcId,.CidrBlock, (.Tags[]|select(.Key=="Name")|.Value)' \
  && printf '\0'
)

Upvotes: 2

Related Questions