Bash command in variable with herestring as input

221 views Asked by At

Using bash, I have a need to echo a series of commands before I run them. Take this example, which is nice and easy and works as expected. Note that all code examples have been run through ShellCheck which reports no issues detected.

OUTPUTS_CMD=(aws cloudformation describe-stacks --stack-name "#{StackName}" --query 'Stacks[0].Outputs')
echo "${OUTPUTS_CMD[*]}"
OUTPUTS=$("${OUTPUTS_CMD[@]}")

However, other commands require input, and while I can successfully echo these commands, I can't actually get them to run.

GET_FUNCTION_NAME_CMD=(jq --raw-output "'map(select(.OutputKey == \"ProxyFunctionName\")) | .[].OutputValue'")
echo "${GET_FUNCTION_NAME_CMD[*]} <<< \"\$OUTPUTS\""
FUNCTION_NAME=$("${GET_FUNCTION_NAME_CMD[@]}" <<< "$OUTPUTS")

The above example outputs the following, which if copied and pasted returns the correct value.

jq --raw-output 'map(select(.OutputKey == "ProxyFunctionName")) | .[].OutputValue' <<< "$OUTPUTS"

However, the command "${GET_FUNCTION_NAME_CMD[@]}" <<< "$OUTPUTS" returns an error. The same error occurs if I echo "$OUTPUTS" and pipe that in to the command saved in the variable instead of using a herestring, so I believe the error is with how the command is defined in the array.

$ FUNCTION_NAME=$("${GET_FUNCTION_NAME_CMD[@]}" <<< "$OUTPUTS")

jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
'map(select(.OutputKey == "ProxyFunctionName")) | .[].OutputValue'
jq: 1 compile error

How can I get the command in the variable to run with a herestring?


Example value for $OUTPUTS

[
    {
        "OutputKey": "ProxyFunctionName",
        "OutputValue": "MyFunctionName",
        "Description": "Proxy Lambda Function ARN"
    },
    {
        "OutputKey": "ProxyFunctionUrl",
        "OutputValue": "https://my.function.url",
        "Description": "Proxy Lambda Function invocation URL"
    }
]
1

There are 1 answers

2
SergA On
OUTPUTS=$(cat <<JSON
[
    {
        "OutputKey": "ProxyFunctionName",
        "OutputValue": "MyFunctionName",
        "Description": "Proxy Lambda Function ARN"
    },
    {
        "OutputKey": "ProxyFunctionUrl",
        "OutputValue": "https://my.function.url",
        "Description": "Proxy Lambda Function invocation URL"
    }
]
JSON
)
OutputKey=ProxyFunctionName

GET_FUNCTION_NAME_CMD="jq -r '.[] | objects | select(.OutputKey == \"$OutputKey\") | .OutputValue'"
echo "$GET_FUNCTION_NAME_CMD <<<\"\$OUTPUTS\""
# jq -r '.[] | objects | select(.OutputKey == "ProxyFunctionName") | .OutputValue' <<<"$OUTPUTS"
FUNCTION_NAME=$(eval $GET_FUNCTION_NAME_CMD <<<"$OUTPUTS")
echo $FUNCTION_NAME
# MyFunctionName