0

I'm writing a script that searches a bunch of AWS accounts for IP addresses. I'm setting the jq command based on the input of the user.

The error I'm getting is this:

./aws_utils.sh: line 1434: jq -r '.Reservations[].Instances[].PrivateIpAddress': command not found

I'm trying to set the variable that sets the jq command with this code:

echo "Find IP Address in AWS"

echo "Search for Public or Private IP Addresses?"
echo "Enter public/private:"
read -r search_scope

 if [[ "$search_scope" = "public" ]]; then
   set_search="jq -r '.Reservations[].Instances[].PublicIpAddress'"
 elif [[ "$search_scope" = "private" ]]; then
   set_search="jq -r '.Reservations[].Instances[].PrivateIpAddress'"
else
  echo "Invalid Input"
fi

When the script runs this line of code is when the error occurs:

search_result=$(aws ec2 describe-instances --profile="$aws_env" | "$set_search" | /bin/grep -v null | /bin/grep \"$ip_address\")

If I run the same command on the command line, I don't get an error:

aws ec2 describe-instances --profile=nonprod | jq -r '.Reservations[].Instances[].PrivateIpAddress' | /bin/grep -v null | /bin/grep 10.48.167.228
10.48.167.228

Why is the jq command producing a command not found error in the script?

bluethundr
  • 1,005
  • 17
  • 68
  • 141
  • 3
    See [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050). Code should never be stored in variables. – Charles Duffy Jul 03 '18 at 19:58
  • ...though in this case you could just assign a string with the jq query, vs one with the whole command. `query='.Reservations[].Instances[].PublicIpAddress'`, and then later calling `jq -r "$query"`, sidesteps the issues at hand. – Charles Duffy Jul 03 '18 at 20:10
  • You may not even need `jq` or `grep`; `aws` can use [JMESPath](http://jmespath.org) (via the `--query` option) to do a lot of your filtering for you. – chepner Jul 03 '18 at 20:11
  • Something like ``aws ec2 describe-instances --query '.Reservations[*].Instances[?PublicIpAddress == `10.48.167.228`]``. – chepner Jul 03 '18 at 20:17
  • I tried both putting the jq command into their own functions and setting a variable with just the query passed to the jq command. Both work! thank you! – bluethundr Jul 03 '18 at 20:25

1 Answers1

1

If you want to store code, store it in a function. You can conditionally define them as much as anything else:

if [[ "$search_scope" = "public" ]]; then
  search_json() { jq -r '.Reservations[].Instances[].PublicIpAddress' "$@"; }
elif [[ "$search_scope" = "private" ]]; then
  search_json() { jq -r '.Reservations[].Instances[].PrivateIpAddress' "$@"; }
else
  echo "Invalid Input" >&2; exit 1;
fi

...and later:

ip_address=$(curl http://example.com/json | search_json)
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441