[英]No error message from curl
I would like to know why the following bash script swallows the error message. 我想知道为什么以下bash脚本吞没了错误消息。
#!/bin/sh
set -eu
LATEST=$(curl -s https://api.github.com/repos/dnote-io/cli/tags | grep -Eo '"name": "v\d*\.\d*\.\d*",' | head -n 1 | sed 's/[," ]//g' | cut -d ':' -f 2)
if [ -z $LATEST ]; then
echo "Error fetching latest version. Please try again."
exit 1
fi
....
Basically, the script fetches something and assigns the result to a variable LATEST
. 基本上,脚本会获取内容并将结果分配给变量
LATEST
。 But when the fetching goes wrong, the script does not print the actual error message from curl
. 但是,当提取错误时,脚本不会从
curl
打印实际的错误消息。
Any ideas or suggestions on how to not ignore the error? 关于如何不忽略错误的任何想法或建议?
What error message? 什么错误消息?
-s
,--silent
-s
,----silent
Silent or quiet mode.静音或安静模式。 Don't show progress meter or error messages.
不要显示进度表或错误消息。 Makes Curl mute.
使Curl静音。
Use -sS
instead. 使用
-sS
代替。
-S
,--show-error
-S
,--show-error
When used with-s
it makes curl show an error message if it fails.与
-s
使用时,如果curl失败,它将使curl显示一条错误消息。
There are other problems in your script: 您的脚本中还有其他问题:
LATEST
, but this may not always be the case, if curl manages to connect but the connection is interrupted while it's downloading the data. LATEST
输出为空,但是,如果curl设法连接但下载数据时连接中断,则情况并非总是如此。 pipefail
option. pipefail
选项来捕获管道左侧的故障。 If you want to keep going, check PIPESTATUS
, but note that you'd have to do this inside the command substitution. PIPESTATUS
,但请注意,您必须在命令替换内执行此操作。 [ -z $LATEST ]
is wrong because the value of LATEST
is split into whitespace-delimited words which are interpreted as wildcard patterns. [ -z $LATEST ]
是错误的,因为LATEST
的值被分成空格分隔的单词,这些单词被解释为通配符模式。 It'll work if the value doesn't contain any special characters, but this is fragile, especially since you're parsing downloaded content. [[ … ]]
syntax, which doesn't require double quotes (except on the right-hand side of comparison operators, and if you don't like remembering these exceptions, just use double quotes all the time). [[ … ]]
语法,该语法不需要双引号(比较运算符右侧的除外,如果您不喜欢记住这些异常,则只需使用始终使用双引号)。 #!/bin/bash
set -eu
set -o pipefail
LATEST=$(curl -s https://api.github.com/repos/dnote-io/cli/tags | grep -Eo '"name": "v\d*\.\d*\.\d*",' | head -n 1 | sed 's/[," ]//g' | cut -d ':' -f 2)
if [ -z "$LATEST" ]; then
echo >&2 "Download from github successful, but extracting the version failed."
exit 1
fi
There are two factors here which both contribute. 这里有两个因素共同起作用。
You are running curl
in a pipeline. 您正在管道中运行
curl
。 The set -e
functionality only applies to the last command in a pipe; set -e
功能仅适用于管道中的最后一个命令; this is how the shell is designed. 这就是外壳的设计方式。
There is no error message from curl
because you are running it with -s
. 没有来自错误消息,
curl
,因为你与运行它-s
。
Capturing the output from a command and checking its exit status at the same time is easy, but then you end up with the results in a shell variable. 捕获命令的输出并同时检查其退出状态很容易,但是最终将结果存储在shell变量中。 Depending on your scenario, this may or may not be cumbersome.
根据您的情况,这可能会或可能不会很麻烦。
if curlout=$(curl -s https://api.github.com/repos/dnote-io/cli/tags); then
# curl succeeded; *now* parse the result
latest="$(sed -n 's/.*"name": "\(v\[0-9]*\.\[0-9]*\.\[0-9]*\)",.*/!d;s//\1/;q' <<<"$curlout")"
else
rc=$?
echo "$0: curl failed: $rc" >&2
exit "$rc"
fi
I refactored your long pipeline into a single sed
script, since that was relatively easy to do. 我将您的长管道重构为一个
sed
脚本,因为这样做相对容易。 I still doubt you can find many grep -E
implementations which actually understand the Perl regex-ism \\d
so maybe your code simply wasn't actually working. 我仍然怀疑您会发现许多
grep -E
实现实际上了解Perl regex-ism \\d
因此也许您的代码实际上并没有真正起作用。 If the result is JSON, the proper solution would be to use a proper JSON parser like jq
instead. 如果结果是JSON,则正确的解决方案是改用
jq
类的正确JSON解析器。
Also notice how your variables should be lower case; 还要注意您的变量应如何小写。 uppercase variables are generally reserved for system use.
大写变量通常保留供系统使用。
Your shebang says #!/bin/sh
so you can't use Bash features like pipefail
with that. 您的shebang会说
#!/bin/sh
因此您不能使用像pipefail
这样的Bash功能。 Perhaps you actually want #!/bin/bash
in the shebang so you can use Bash features in your script (seeing as you tagged this question bash anyway). 也许您实际上想要在shebang中使用
#!/bin/bash
以便您可以在脚本中使用Bash功能(无论如何,您始终在标记此问题bash时看到)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.