我在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/resource
或f http://example.com/resource p1=v1 p2=v2
那样调用,问题是当DATA_OPTION
和PARAMS
为空时,在这种情况下,Bash将两个空参数传递给curl,curl随后将其识别为URL,并生成以下丑陋的消息:
curl: (3) <url> malformed
curl: (3) <url> malformed
我使用if/else临时解决了这个问题,因此DATA_OPTION
和PARAMS
根本不被传递:
[..]
if [ -z "${PARAMS}" ]; then
curl -o - --data "${PARAMS}" "${URL}"
else
curl -o - "${URL}"
fi
}
但这对我来说似乎很难。有更优雅的解决方案吗?注意,需要在PARAMS
周围加上引号,因为一些参数值可能包含空格。
3条答案
按热度按时间bzzcjhmw1#
实际上,您可以使用参数扩展中的“use alternate value”选项(
:+
)来干净地解决这个问题:如果PARAMS为空或未定义,则整个
${PARAMS:+"--data" "$PARAMS"}
的值为空字符串,并且由于它不是双引号,单词拆分会将其完全删除;另一方面,如果PARAMS为非空,则它实际上会被"--data" "$PARAMS"
替换,这正是您想要的。[EDIT]这可以在大多数POSIX风格的shell中使用,但不能在zsh中使用,因为zsh不会对扩展进行单词分割,即使扩展没有引号。如果你想在zsh(以及bash、dash、ksh等)中使用,你需要将选项标签设置为一个单独的条件项:
j9per5c42#
我觉得这是慵懒与优雅的完美结合:
是的,这里有一个无用的
&
,问题是它不会伤害任何人,它很短,而且它应该对你的两种情况都有效,不管你在PARAMS
中有没有任何东西。aydmsdu93#
使用bash数组生成命令
为此我经常使用bash数组!
注意,使用
IFS='&'
合并参数与&
是更快和更简单!您的功能将变为:
注意:避免使用大写的变量名!最好使用驼峰式的小写!