如何(不)将空引用变量作为参数传递给命令

时间:2013-11-30 23:12:00

标签: bash shell

我在bash脚本中有一个函数,看起来像这样(简化):

# 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}"
}

可以像f http://example.com/resourcef http://example.com/resource p1=v1 p2=v2一样调用它。问题是DATA_OPTIONPARAMS为空时。在这种情况下,Bash将两个空参数传递给curl,然后通过curl将其识别为URL并生成以下丑陋的消息:

curl: (3) <url> malformed
curl: (3) <url> malformed

我暂时使用if / else解决了问题,因此根本没有传递DATA_OPTIONPARAMS

    [..]

    if [ -z "${PARAMS}" ]; then
        curl -o - --data "${PARAMS}" "${URL}"
    else
        curl -o - "${URL}"
    fi
}

但这对我来说似乎很难看。有更优雅的解决方案吗?请注意,需要PARAMS左右的引号,因为某些参数值可能包含空格。

2 个答案:

答案 0 :(得分:8)

您可以在参数扩展中使用“使用备用值”选项(:+)干净利落地解决这个问题:

curl -o - ${PARAMS:+"--data" "$PARAMS"} "${URL}"

如果PARAMS为空或未定义,则整个${PARAMS:+"--data" "$PARAMS"}事物评估为空字符串,并且因为它不是双引号,所以单词拆分会完全删除它。另一方面,如果PARAMS是非空的,它会被"--data" "$PARAMS"有效地取代,这正是你想要的。

答案 1 :(得分:1)

我认为这是懒惰和优雅的完美结合:

curl -o - --data "&$PARAMS" "$URL"

没错,那里有一个无用的&。问题是它没有伤害任何人,它很短,它应该适用于你的两种情况,无论你是否有任何PARAMS