[英]No error message from curl
我想知道為什么以下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
....
基本上,腳本會獲取內容並將結果分配給變量LATEST
。 但是,當提取錯誤時,腳本不會從curl
打印實際的錯誤消息。
關於如何不忽略錯誤的任何想法或建議?
什么錯誤消息?
-s
,----silent
靜音或安靜模式。 不要顯示進度表或錯誤消息。 使Curl靜音。
使用-sS
代替。
-S
,--show-error
與-s
使用時,如果curl失敗,它將使curl顯示一條錯誤消息。
您的腳本中還有其他問題:
LATEST
輸出為空,但是,如果curl設法連接但下載數據時連接中斷,則情況並非總是如此。 pipefail
選項來捕獲管道左側的故障。 如果要繼續,請檢查PIPESTATUS
,但請注意,您必須在命令替換內執行此操作。 [ -z $LATEST ]
是錯誤的,因為LATEST
的值被分成空格分隔的單詞,這些單詞被解釋為通配符模式。 如果該值不包含任何特殊字符,它將起作用,但這很脆弱,尤其是因為您正在解析下載的內容。 請參閱為什么我的shell腳本在空白或其他特殊字符上會阻塞? 。 始終在變量和命令替換周圍使用雙引號,除非您知道為什么需要將其保留。 另外,在bash中而不在sh中,請使用[[ … ]]
語法,該語法不需要雙引號(比較運算符右側的除外,如果您不喜歡記住這些異常,則只需使用始終使用雙引號)。 #!/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
這里有兩個因素共同起作用。
您正在管道中運行curl
。 set -e
功能僅適用於管道中的最后一個命令; 這就是外殼的設計方式。
沒有來自錯誤消息, curl
,因為你與運行它-s
。
捕獲命令的輸出並同時檢查其退出狀態很容易,但是最終將結果存儲在shell變量中。 根據您的情況,這可能會或可能不會很麻煩。
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
我將您的長管道重構為一個sed
腳本,因為這樣做相對容易。 我仍然懷疑您會發現許多grep -E
實現實際上了解Perl regex-ism \\d
因此也許您的代碼實際上並沒有真正起作用。 如果結果是JSON,則正確的解決方案是改用jq
類的正確JSON解析器。
還要注意您的變量應如何小寫。 大寫變量通常保留供系統使用。
您的shebang會說#!/bin/sh
因此您不能使用像pipefail
這樣的Bash功能。 也許您實際上想要在shebang中使用#!/bin/bash
以便您可以在腳本中使用Bash功能(無論如何,您始終在標記此問題bash時看到)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.