考虑一下,我有一个shell脚本abc.sh
execute_curl() {
curl_command="curl"
for arg in "$@"; do
curl_command=$(printf "%s %s" "$curl_command" "$arg")
done
eval "$curl_command"
}
URL='https://some.github.com/api/v3/repos/gimlet-dev-repos/repository-name/contents/file.name?ref=branch-name’
execute_curl -s -H “Authorization: token ${TOKEN}” -H "Accept: application/vnd.github.v3+json" -L ”${URL}"
和test.bats为同一
@test "test-run-command perform" {
export PATH="${RESOURCES_DIR}/mocks/:${PATH}"
TEMP_DIR=$(mktemp -d)
debug "TEMP_DIR: ${TEMP_DIR}"
run abc -t TOKEN -d 'some.github.com' -o 'myorg' -r 'myrepo' -g "${RESOURCES_DIR}/mock-global" -b branch -a "${TEMP_DIR}"
assert_success
}
在mocks目录中,我有curl文件来测试curl: 例如:
#!/bin/sh
string_matches_glob() {
eval "
case \$1 in
$2) return 0 ;;
*) return 1 ;;
esac
"
}
while getopts "H:L:o:w:" OPT; do
case "${OPT}" in
o) OUTPUT_FILE="${OPTARG}" ;;
L) CURL_URL="${OPTARG}" ;;
?) ;;
esac
done
if string_matches_glob "${CURL_URL}" ‘*/contents/file.name*’; then
echo '
Content…
' >"${OUTPUT_FILE}"
printf '%s' '200'
else
exit 97
fi
问题是,如果我不使用execute_curl,而是直接使用带参数的curl命令,测试会通过,但当我使用execute_curl函数时,测试会失败,并显示97。
以上curl文件的详细说明:
string_matches_glob计算第一个参数是否匹配第二个参数中指定的glob模式。然后,脚本使用getopts命令解析传递给脚本的命令行选项和参数。
有三个选项可以传递给脚本:
-o:指定脚本要写入的输出文件-L:指定要传递给string_matches_glob的URL
如果URL与任何指定的模式都不匹配,脚本将退出,并显示错误代码97。
我的想法是这一行无法匹配curl_url:
if string_matches_glob“${CURL_URL}”'*/contents/file.name *'
你能帮我修改一下curl文件吗?这样测试就能通过了。
1条答案
按热度按时间p8ekf7hl1#
当我调用
bash abc.sh
时,调用似乎可以工作。但是,当调试(使用
TOKEN=foo bash -x abc.sh
)显示执行的命令是:因此,立即突出的一点是,
curl_command
的构建和执行方式没有正确处理空白。curl
将看到-H Authorization:
和-H Accept:
,但忽略所提供的头的实际值。在很棒的BashFAQ上有一个页面专门介绍了如何正确地做到这一点的陷阱:http://mywiki.wooledge.org/BashFAQ/050
使用适当的解决方案还可以消除对
eval
的需求:这将创建预期的
curl
命令,并使用适当的空格:不确定这是否会解决您的问题,但至少对
curl
的调用将是正确的。接下来突出的是,测试中的调用与
curl
调用不匹配。比如,这个调用:
将构成此
curl
调用:我觉得这不是你想要的
这让我认为,真实的代码中的内容比最小示例中所表示的内容要多。
最有可能的答案是
curl_command
使用输入来构造正确的URL(-d
= 'domain',-o
= 'org',-r
='repo'?)但那只是一个猜测。最后,让我们在
string_matches_glob
中处理eval
。我假设这是为了允许动态匹配$1
和$2
。如果是这种情况,有更简单的方法来做到这一点,没有eval
或case。 例如,使用
=~`正则表达式匹配运算符:或者,如果不可用或不需要,则使用
grep
:由于这两种解决方案都足够小,因此可以内联使用,而不需要单独的函数:
或:
你可能想知道“为什么这很重要?“但是代码中的魔法越少,调试就越容易。
所有这些都让我觉得我们没有足够的真实的代码来正确地调试这个问题,尽管最有可能的罪魁祸首是
curl_command
结构。