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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With