Reputation: 1160
I have a variable named $db_main_info
that contains the following string
{ "host": "env-prod-blah-db.blah.us-east-1.rds.amazonaws.com", "dbname": "blahblah", "user": "foobar", "password": "foopassfoopass" }
I am doing the following
read host dbname user password < <(echo $db_main_info | jq -r '.host, .dbname, .user, .password')
After executing the above statement when i do echo $host
it prints the following
env-prod-blah-db.blah.us-east-1.rds.amazonaws.com
However the other 3 variables dbname
,user
and password
never get set. I am not sure what i am doing wrong?
I expect the variable dbname
to take the value blahblah
and the variable user to take the value foobar
and the variable password
to take the value foopassfoopass
Upvotes: 0
Views: 1076
Reputation: 10133
jq
prints each field on a separate line, but read
reads, by default, one line only. One method is to modify the default behaviour of read
, by assigning the newline character to the IFS
, which sets this character to be used as the field separator, and setting the line delimiter to the null string (so that newline no longer serves as a delimiter to indicate the end of line):
#!/bin/bash
db_main_info='{ "host": "env-prod-blah-db.blah.us-east-1.rds.amazonaws.com", "dbname": "blahblah", "user": "foobar", "password": "foopassfoopass" }'
IFS=$'\n' read -r -d '' host dbname user password < <(jq -r '.host, .dbname, .user, .password' <<< "$db_main_info")
echo "host=$host"
echo "dbname=$dbname"
echo "user=$user"
echo "password=$password"
Upvotes: 6
Reputation: 123640
You can run jq
alone to see what the problem is:
$ echo "$db_main_info" | jq -r '.host, .dbname, .user, .password'
env-prod-blah-db.blah.us-east-1.rds.amazonaws.com
blahblah
foobar
foopassfoopass
There's four lines with one field each. You were assuming it was one line with four fields.
You can instead read multiple lines and assign each to the variable:
db_main_info=' { "host": "env-prod-blah-db.blah.us-east-1.rds.amazonaws.com", "dbname": "blahblah", "user": "foobar", "password": "foopassfoopass" }'
for var in host dbname user password
do
IFS='' read -r "$var"
done < <(echo "$db_main_info" | jq -r '.host, .dbname, .user, .password')
echo "Host: $host, DB name: $dbname, user: $user, password: $password"
This results in:
Host: env-prod-blah-db.blah.us-east-1.rds.amazonaws.com, DB name: blahblah, user: foobar, password: foopassfoopass
Upvotes: 1