Search code examples
bashshellcurlshellcheck

Optionally include a user and password in curl request?


I am optionally including a user and password in a curl request as follows:

declare creds=""
if [ -n "$user" ] && [ -n "$password" ]; then
    creds="-u ${user}:${password}"
fi

output=$(curl ${creds} -X PUT -v --write-out "%{http_code}" "$url" \
                  -H 'Content-Type: application/json' -s -o /dev/null --data "${payload}")

This seems to work fine, but I'm getting this shellcheck warning:

Double quote to prevent globbing and word splitting

https://github.com/koalaman/shellcheck/wiki/SC2086

Puting quotes around it doesn't work, e.g. if I do this:

output=$(curl "${creds}" -X PUT -v --write-out "%{http_code}" "$url" \
                  -H 'Content-Type: application/json' -s -o /dev/null --data "${payload}")

then when the username and password are not supplied, this results in empty double quotes in the curl request curl "" -X PUT ..., which generates a <url> malformed error.

I could use an if-else for the curl command, but I'd rather avoid the duplication. Is the above approach acceptable despite the shellcheck warning?


Solution

  • You were doing right in putting quotes around the variable, but shellcheck doesn't catch the issue of storing commands in a variable which has its own downfalls. Since this being a an issue with function of the shell, shellcheck can't quite catch it out-of-the-box. When you did below

    creds="-u ${user}:${password}"
    

    and quoted "$creds", it is passed as one single argument word to curl instead of being broken down to -u and "${user}:${password}" separately. The right approach should have been to use an array to store the commands and expand it, so that the words are preserved and not split by the shell (foremost reason to quote the variable, as indicated by shellcheck)

    creds=(-u "${user}:${password}")
    

    and invoke

    curl "${creds[@]}" <rest-of-the-cmd>
    

    Also explore the following

    1. I'm trying to put a command in a variable, but the complex cases always fail!
    2. How to store a command in a variable in a shell script?