【问题标题】:Curl in Bash, Redirect STDERR to file except for progress stderr在 Bash 中卷曲,将 STDERR 重定向到文件,除了进度 stderr
【发布时间】:2016-01-07 03:33:43
【问题描述】:

我的 shell 脚本将文件上传到服务器。我希望 stdout 和 stderr 同时写入文件和控制台。但我不希望stderr 的进度条/百分比进入文件。我只想将 curl 错误写入文件。

最初我有这个

curl ...  2>> "$log"

这将漂亮整洁的 1 行或多行下载写入日志文件,但没有任何内容可供控制台使用。

然后我把它改成了

curl ... 3>&1 1>&2 2>&3 | tee -a "$log"

这写到控制台和文件,耶!除了它将每个百分比的整个进度写入文件,使日志文件非常大并且阅读起来很乏味。

如何在控制台查看进度,但只将输出的最后一部分写入文件?

我想要这个

 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
  106  1166    0     0  106  1166      0   2514 --:--:-- --:--:-- --:--:--  2 106  1166    0     0  106  1166      0    795  0:00      :01  0:00:01 --:--:--     0 106  1166    0     0  106  1166      0    660  0:00:01  0:00:01 --:--:--     0

这就是我通过第二个 curl 重定向得到的结果

 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                             Dload  Upload   Total   Spent    Left  Speed



 0  9.8G    0     0    0 16384      0  24764   4d 22h --:--:--   4d 22h 24764
  0  9.8G    0     0    0 3616k      0  4098k  0:41:54 --:--:--  0:41:54 15.9M
  0  9.8G    0     0    0 24.2M      0  12.9M  0:12:59  0:00:01  0:12:58 19.8M
  0  9.8G    0     0    0 50.4M      0  17.5M  0:09:34  0:00:02  0:09:32 22.7M
  0  9.8G    0     0    0 79.8M      0  20.5M  0:08:09  0:00:03  0:08:06 24.7M
  1  9.8G    0     0    1  101M      0  20.7M  0:08:04  0:00:04  0:08:00 24.0M
  1  9.8G    0     0    1  129M      0  21.9M  0:07:37  0:00:05  0:07:32 25.1M
  1  9.8G    0     0    1  150M      0  21.8M  0:07:41  0:00:06  0:07:35 25.1M
  1  9.8G    0     0    1  169M      0  21.5M  0:07:47  0:00:07  0:07:40 23.8M
  1  9.8G    0     0    1  195M      0  21.9M  0:07:38  0:00:08  0:07:30 23.0M
  2  9.8G    0     0    2  219M      0  22.1M  0:07:33  0:00:09  0:07:24 23.5M
  2  9.8G    0     0    2  243M      0  22.4M  0:07:29  0:00:10  0:07:19 22.9M
  2  9.8G    0     0    2  273M      0  22.9M  0:07:17  0:00:11  0:07:06 24.6M
..
.. hundreds of lines...
..
99  9.8G    0     0   99 9982M      0  24.8M  0:06:45  0:06:41  0:00:04 24.5M
 99  9.8G    0     0   99  9.7G      0  24.8M  0:06:44  0:06:42  0:00:02 24.9M
 99  9.8G    0     0   99  9.8G      0  24.8M  0:06:44  0:06:43  0:00:01 26.0M
100  9.8G    0     0  100  9.8G      0  24.8M  0:06:44  0:06:44 --:--:-- 25.8M

编辑: 我不明白的是根据http://www.tldp.org/LDP/abs/html/io-redirection.html

2>filename
  # Redirect stderr to file "filename."

但如果我使用它,我不会得到文件中的每一个 stderr 进度行。如果我尝试任何其他解决方案,每个 stderr 进度行都会重定向到文件

【问题讨论】:

  • 那么对于第二次卷曲,你需要100 9.8G 0 0 100 9.8G 0 24.8M 0:06:44 0:06:44 --:--:-- 25.8M(除了标题)?
  • 是的,一两行,除了任何 curl 响应代码 (28) 超时等外,还显示最后一个百分比(100% 或例如 50%,如果它在中途崩溃)

标签: shell curl


【解决方案1】:

就像视频是一系列帧一样,控制台中的更新百分比也是一系列行。文件中的内容是真正的输出。不同之处在于文本文件中的回车将以下文本放在下面,而在控制台中它会覆盖当前行。

如果您想在控制台中查看更新百分比,而不是文件,您可以使用以下内容:

curl |& tee >(sed '1b;$!d' > log)

或者:

curl |& tee /dev/tty | sed '1b;$!d' > log

【讨论】:

  • 请解释一下 1b;$!d
  • @Jabda 它只打印第一行和最后一行
  • 我是保留 3>&1 1>&2 2>&3 |& 还是没有 &。 curl 代码会显示在控制台和文件中吗?比如 curl (28) 超时
  • @Jabda |& 应该取代你所拥有的重定向去
  • 它不起作用。我得到了日志中的每一行。 curl ... |& tee >(sed '1b;$!d' > "$log")
【解决方案2】:

假设您有 10 个巨大的 .txt 文件 test1.txt ... test10.txt

以下是使用单个 cURL 命令上传它们并记录结果而不记录进度表的方法,诀窍是使用man file 中的--write-out-w 选项,这些都是相关的上传到 FTP 的字段:

curl -T "test[1-10:1].txt" -u user:password sftp://example.com:22/home/user/ -# -k -w "%{url_effective}\t%{ftp_entry_path}\t%{http_code}\t%{http_connect}\t%{local_ip}\t%{local_port}\t%{num_connects}\t%{num_redirects}\t%{redirect_url}\t%{remote_ip}\t%{remote_port}\t%{size_download}\t%{size_header}\t%{size_request}\t%{size_upload}\t%{speed_download}\t%{speed_upload}\t%{ssl_verify_result}\t%{time_appconnect}\t%{time_connect}\t%{time_namelookup}\t%{time_pretransfer}\t%{time_redirect}\t%{time_starttransfer}\t%{time_total}\n" >> log.txt

对于您的 log.txt 文件,您可能需要先添加列标题:

echo -e "url_effective\tftp_entry_path\thttp_code\thttp_connect\tlocal_ip\tlocal_port\tnum_connects\tnum_redirects\tredirect_url\tremote_ip\tremote_port\tsize_download\tsize_header\tsize_request\tsize_upload\tspeed_download\tspeed_upload\tssl_verify_result\ttime_appconnect\ttime_connect\ttime_namelookup\ttime_pretransfer\ttime_redirect\ttime_starttransfer\ttime_total" > log.txt -# 使进度条更整洁,例如: ######################################################################## 100.0% ######################################################################## 100.0%

...curl -T "test[1-10:1].txt" 可让您指定要上传的文件范围。

【讨论】:

  • 这很好用,除了 stderr 只进入控制台。如果它同时进入控制台和日志,那将是完美的。关于重定向的一些事情
  • 这几乎是对的。 |& tee -a "$log" 会将stderr(卷曲错误)打印到文件中,但它也会将#s 打印到文件中,这是不需要的
  • 尝试使用sed 过滤掉进度表(替换>>log.txt):2>&1 | tee -a log.txt && sed '/######################################################################## 100.0%/d' log.txt >> log_clean.txt
  • 尝试 grep -v '#' log.txt >> log_clean.txt 代替 sed
  • 最好的解决方案是抑制进度条并使用带有 -sS 选项的标题写入,例如: curl -sS ....... -w "$curlwrite" |& tee -a “$log”。
猜你喜欢
  • 2014-07-22
  • 2010-09-30
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2021-06-29
  • 2014-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多