Simplify Long Bash Commands by using Arrays

Consider the following sample bash script:

#!/bin/bash

TARGET_BRANCH_IS_AT_COMMIT=68dccccccccccccccccccccccccccccccccccccc
SCAN_BRANCH_NAME=main
GIT_REPO="my-git-username/sample-repo"

if ! gh api \
    "/repos/${GIT_REPO}/code-scanning/analyses" \
    --paginate --jq "[.[]|select(.ref==\"refs/heads/${SCAN_BRANCH_NAME}\" \
    and .commit_sha==\"${TARGET_BRANCH_IS_AT_COMMIT}\")|.created_at[:-10]] \
    |unique|max" >/dev/stdout 2>/dev/null; \
then
    echo "failed"
else
    echo "successful"
fi

An if statement at line 7 performs a check on the execution status of a long command:

gh api \
    "/repos/${GIT_REPO}/code-scanning/analyses" \
    --paginate --jq "[.[]|select(.ref==\"refs/heads/${SCAN_BRANCH_NAME}\" \
    and .commit_sha==\"${TARGET_BRANCH_IS_AT_COMMIT}\")|.created_at[:-10]] \
    |unique|max" >/dev/stdout 2>/dev/null;

Using Arrays to Store/Execute Commands

  • From the previous section, the command can be stored in an array, CMD_TO_RUN
CMD_TO_RUN=( gh api \
"/repos/${GIT_REPO}/code-scanning/analyses" \
--paginate --jq "[.[]|select(.ref==\"refs/heads/${SCAN_BRANCH_NAME}\" \
and .commit_sha==\"${TARGET_BRANCH_IS_AT_COMMIT}\")|.created_at[:-10]] \
|unique|max" )
  • Update the initial script to execute the array as a command and store the output in variable CMD_OUTPUT, i.e.,
...
if ! CMD_OUTPUT=$( "${CMD_TO_RUN[@]}" >/dev/stdout 2>/dev/null ); then
...
  • The final revised script should look like:
#!/bin/bash

TARGET_BRANCH_IS_AT_COMMIT=68dccccccccccccccccccccccccccccccccccccc
SCAN_BRANCH_NAME=main
GIT_REPO="my-git-username/sample-repo"

# Construct the command and store in an array
CMD_TO_RUN=( gh api \
"/repos/${GIT_REPO}/code-scanning/analyses" \
"--paginate" "--jq" "[.[]|select(.ref==\"refs/heads/${SCAN_BRANCH_NAME}\" \
and .commit_sha==\"${TARGET_BRANCH_IS_AT_COMMIT}\")|.created_at[:-10]] \
|unique|max" )

# Execute the command and decide on course of action based on output returned
if ! CMD_OUTPUT=$( "${CMD_TO_RUN[@]}" >/dev/stdout 2>/dev/null ); then
    echo "failed with output: ${CMD_OUTPUT}"
else
    echo "successfully executed with output: ${CMD_OUTPUT}"
fi