CURL: 上传时如何显示进度信息?

我使用以下语法上传文件:

curl --form upload=@localfilename --form press=OK [URL]

如何显示进度? 谢谢。

106168 次浏览

下面是我在构建脚本中使用的内容:

curl "${UPLOAD_URL}" \
--progress-bar \
--verbose \
-F build="${BUILD}" \
-F version="${VERSION}" \
-F ipa="@${IPA};type=application/octet-stream" \
-F assets="@-;type=text/xml" \
-F replace="${REPLACE}" \
-A "${CURL_FAKE_USER_AGENT}" \
<<< "${ASSETS}" \
| tee -a "${LOG_FILE}" ; test ${PIPESTATUS[0]} -eq 0

-F-A选项可能不会让你感兴趣,但有用的部分是:

curl "${UPLOAD_URL}" --progress-bar

它告诉 curl在上传过程中显示一个进度条(而不是默认的“进度计”) ,并且:

 | tee -a "${LOG_FILE}" ; test ${PIPESTATUS[0]} -eq 0

它将命令的输出附加到一个日志文件,并将其 echo 到 stdouttest ${PIPESTATUS[0]} -eq 0部分使这一行的退出状态(在 bash 脚本中)与 curl命令返回的退出代码相同,而不是 tee命令的退出状态(这是必要的,因为 tee实际上是在这一行中执行的最后一个命令,而不是 curl)。


来自 man curl:

PROGRESS METER
curl normally displays a progress meter during operations, indicating the
amount of transferred data, transfer speeds and estimated time left, etc.


curl  displays  this  data to the terminal by default, so if you invoke curl
to do an operation and it is about to write data to the terminal, it disables
the progress meter as otherwise it would mess up the output mixing progress
meter and response data.


If you want a progress meter for HTTP POST or PUT requests, you need to
redirect the response output to a file, using shell redirect (>), -o [file]
or similar.


It is not the same case for FTP upload as that operation does not spit out
any response data to the terminal.


If you prefer a progress "bar" instead of the regular meter, -# is your
friend.


OPTIONS
-#, --progress-bar
Make curl display progress as a simple progress bar instead of the
standard, more informational, meter.

我在接受答案的命令重定向时遇到了麻烦,发现 -o选项将把响应输出放在一个允许显示进度条的文件中。

curl --progress-bar \
-o upload.txt \
-H ${SOME_AUTH_HEADER} \
-T ${SOME_LARGE_FILE} \
"${UPLOAD_URL}"

只是另一个选择,以获得期望的结果。


注意 : 在手册页中强调这一行对于理解为什么在指定 --progress-bar时没有显示进度条的根本原因很重要。

      If you want a progress meter for HTTP POST or PUT requests,
you need to redirect the response output to a file,
using shell redirect (>), -o [file] or similar.

这里的所有其他答案都存在这样的问题: 它们要求您将 curl 的原始输出写入(log)文件。然而,这并不是所有情况下都需要的。

问题在于,当需要服务器响应时,curl 会隐藏进度条/计量表,然后将其写入标准输出。 因此,基本上您可以将输出重定向到一个文件,以再次显示工具条。但是我们不希望这样,所以 /dev/nulltee可以在这里帮助我们:

curl --progress-bar -T "${SOME_LARGE_FILE}" "${UPLOAD_URL}" | cat

Curl 的输出被传递给 teetee将输出写入控制台(我们希望看到进度条和服务器响应)和文件(我们不需要它,但是当我们使用 /dev/null时,这并不重要)。

注意,curl devs 当然不会为了好玩而隐藏进度条。在这种情况下,您可能不会总是看到服务器的结果,或者它可能只显示几秒钟(因为之后会再次显示进度条) ,但是如果您不关心这一点,那么这个解决方案是一个很好的解决方案。

在 Windows 上显示进度条: Curl —— Progress-bar —— load-file Myfile.zip“ https://my.upload.site/some/upload/path/Myfile.zip" ; | type

对于那些希望从 stderr 转移到 stdout 的用户:

curl ... -o ... ... 2>&1 | sed -E 's/\r([^\n])/\n\1/g' | grep -P '^(?:  [% ] |(?:  |  \d|\d\d)\d |[<>] )'

tested on download

必须使用 sed通过将 CR替换为 LF来忽略空行。 这是在详细或非详细模式下统一解析 curl 输出所必需的。