How to (not) pass empty quoted variables as arguments to commands
bash, shell
Solution
You can actually solve this cleanly with the "use alternate value" option (`:+`) in a parameter expansion:
curl -o - ${PARAMS:+"--data" "$PARAMS"} "${URL}"
If PARAMS is empty or undefined, the whole `${PARAMS:+"--data" "$PARAMS"}` thing evaluates to the empty string, and since it's not double-quoted, word splitting removes it entirely. On the other hand, if PARAMS is nonblank, it gets effectively replaced by `"--data" "$PARAMS"`, which is exactly what you want.
[EDIT] This will work in most POSIX-ish shells, but not zsh, since zsh doesn't word-split expansions even if they're unquoted. If you want this to work in zsh (as well as bash, dash, ksh, etc) you need to make the option label a separate conditional item:
curl -o - ${PARAMS:+"--data"} ${PARAMS:+"$PARAMS"} "${URL}"
Problem
I have a function in a bash script that looks like this (simplified): ``` # Usage: f URL [PARAMETER]... f() { local URL="$1"; shift local PARAMS for arg in "$@"; do PARAMS="${PARAMS}&${arg}" done PARAMS="${PARAMS#'&'}" local DATA_OPTION [ -z "${PARAMS}" ] || DATA_OPTION='--data' curl -o - "${DATA_OPTION}" "${PARAMS}" "${URL}" } ``` It can be called like `f http://example.com/resource` or `f http://example.com/resource p1=v1 p2=v2`. The problem is when `DATA_OPTION` and `PARAMS` are empty. In this case, Bash passes two empty arguments to curl, which are then recognised as URLs by curl and produce the following ugly message: ``` curl: (3) <url> malformed curl: (3) <url> malformed ``` I temporarily solved the problem using an if/else so that `DATA_OPTION` and `PARAMS` are not passed at all: ``` [..] if [ -z "${PARAMS}" ]; then curl -o - --data "${PARAMS}" "${URL}" else curl -o - "${URL}" fi } ``` but this seems ugly to me. Is there a more elegant solution? Note that the quotes around `PARAMS` are needed because some parameter values may contain spaces.