如何仅显示wget进度条?

110
例如:
wget http://somesite.com/TheFile.jpeg

    downloading: TheFile.tar.gz ...
    --09:30:42--  http://somesite.com/TheFile.jpeg
               => `/home/me/Downloads/TheFile.jpeg'
    Resolving somesite.co... xxx.xxx.xxx.xxx.
    Connecting to somesite.co|xxx.xxx.xxx.xxx|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 1,614,820 (1.5M) [image/jpeg]

    25% [======>                              ] 614,424      173.62K/s    ETA 00:14

How can I get it to look like the following?

    downloading: TheFile.jpeg ...
    25% [======>                              ] 614,424      173.62K/s    ETA 00:14

我知道curl可以做到这一点。然而,我需要让wget来完成这个工作。


1
我认为如果不编写一个解析wget输出的脚本是不可能实现的。wget -nv是你能得到的最接近的方式,但它实际上并没有显示进度条,只有在下载完成时显示一行摘要。 - cdhowie
3
wget --progress=bar:force:noscroll这句话的意思是使用wget下载命令时,显示下载进度条,并强制在同一行上更新进度而不滚动。 - Leo Gallucci
2
curl can download files and produce a simple progress bar: echo "downloading: $file ..." && curl --progress-bar --remote-name --location "$url" - curusarn
9个回答

241

使用:

wget http://somesite.com/TheFile.jpeg -q --show-progress
  • -q:关闭wget的输出。

  • --show-progress:无论wget的详细程度设置如何,都强制wget显示进度条。


13
这对我来说显示了 wget: unrecognized option '--show-progress'?你知道这是否仅存在于较新的wget版本中吗? - Uli Köhler
10
@UliKöhler 提到的旗帜仅自1.16版开始存在。 - Whymarrh
14
不同版本之间肯定会有一些差异,但为了让1.19版本按照广告宣传的那样正常运行,我还需要添加以下选项:--progress=bar:force:noscroll,再加上-q--show-progress。这对于构建中的Dockerfile非常有效。 - YoYo
1
正如@YoYo所提到的,不要忘记使用--progress=bar:force:noscroll来防止产生换行符! - Brent Faust

34

使用以下标志运行:

wget -q --show-progress --progress=bar:force 2>&1

2
最佳单行代码。我不明白为什么它不是被选中的答案。 - Salamandar
force 2>&1 是什么意思?对我来说,只有 wget -q --show-progress --progress=bar 看起来产生了相同的输出。 - MBT
2
这个是赢家。这是一个 Stack Overflow 的 bug,它不是最佳答案。 - mmla
2
@ MBT:“2>&1”简单地将stderr(通常用于错误和日志消息)和stdout(通常用于实际结果)输出组合在一起。猜想在这里是不必要的,但通常当人们想要将进程的完整输出(结果和错误消息)重定向到同一目标时使用它。 - jov14

32

你可以使用以下过滤器:

progressfilt ()
{
    local flag=false c count cr=$'\r' nl=$'\n'
    while IFS='' read -d '' -rn 1 c
    do
        if $flag
        then
            printf '%s' "$c"
        else
            if [[ $c != $cr && $c != $nl ]]
            then
                count=0
            else
                ((count++))
                if ((count > 1))
                then
                    flag=true
                fi
            fi
        fi
    done
}

用法:

$ wget --progress=bar:force http://somesite.com/TheFile.jpeg 2>&1 | progressfilt
100%[======================================>] 15,790      48.8K/s   in 0.3s

2011-01-13 22:09:59 (48.8 KB/s) - 'TheFile.jpeg' saved [15790/15790]

此函数依赖于在进度条开始之前发送一系列的0x0d0x0a0x0d0x0a0x0d。这种行为可能与实现有关。


如果您没有至少1.16版本的wget,这将非常有用! - user2226755
1
为了防止字符编码错误,您需要将 %c 替换为 %s 以修复此问题: - user2226755
@HorsSujet:我看到的是Unicode左右单引号。我会编辑我的答案进行更改。感谢您的报告。 - Dennis Williamson
我能在 wget 在后台运行时实现这个吗? - alper
1
@alper:如果你将一个程序放到后台运行,它的输出将会与其他输出混合在一起,除非你将其重定向到文件中。如果你这样做了,类型将默认为“点”并且你可以根据自己的喜好设置比例尺。例如(显式设置类型):wget --progress=dot:giga URL > progressfile.txt &。然后你可以定期检查文件以查看进度。也许 wc -l progressfile.txt - Dennis Williamson
显示剩余2条评论

13

您可以使用tail命令的follow选项:

wget somesite.com/TheFile.jpeg --progress=bar:force 2>&1 | tail -f -n +6

+6是删除前6行的命令。在你的版本或语言中,可能会有所不同。

你需要使用--progress=bar:force参数,否则wget将切换到“点”类型显示进度。

缺点是刷新频率比wget低(大约每2秒刷新一次)。tail--sleep-interval选项似乎就是为此而设计的,但对我没有任何影响。


你知道为什么它会切换到点类型吗?是某种TERM类型的问题吗?force对我起作用了-谢谢! - Goblinhack
使用此命令只显示进度条,不带目标文件名和尾部值"8"。 wget somesite.com/TheFile.jpeg --progress=bar:force 2>&1 | tail -f -n +8 - M.S. Arun

13

如其他人所指出的,选项--show-progress是最好的选择,但它仅适用于GNU wget 1.16及以上版本,详情请参见wget 1.16中值得注意的更改

为了安全起见,我们可以先检查是否支持--show-progress

# set progress option accordingly
wget --help | grep -q '\--show-progress' && \
  _PROGRESS_OPT="-q --show-progress" || _PROGRESS_OPT=""

wget $_PROGRESS_OPT ...

也许现在是考虑只使用curl的时候了。


4

您可以使用标准选项:

wget --progress=bar http://somesite.com/TheFile.jpeg

1
我不知道其他发行版,但至少在Ubuntu上,这绝对不是OP所要求的内容。即它仍然显示其他信息,但OP要求的是“仅进度条”... - Dee'Kej

2

以下是另一个示例:

download() {
    local url=$1
    echo -n "    "
    wget --progress=dot $url 2>&1 | grep --line-buffered "%" | sed -u -e "s,\.,,g" | awk '{printf("\b\b\b\b%4s", $2)}'
    echo -ne "\b\b\b\b"
    echo " DONE"
}

0

这里有一个解决方案,它将为每个文件(或行)显示一个点。如果您使用--recursive下载,它尤其有用。这不会捕捉错误,并且如果有额外的行可能会略微偏差,但对于大量文件的一般进度来说非常有帮助:

wget -r -nv https://example.com/files/ | \
    awk -v "ORS=" '{ print "."; fflush(); } END { print "\n" }'

-4

这不是一个字面上的答案,但这个代码片段对于一些寻找例如“zenity wget GUI”的人也可能有帮助:

LANG=C wget -O /dev/null --progress=bar:force:noscroll --limit-rate 5k http://nightly.altlinux.org/sisyphus/ChangeLog 2>&1 | stdbuf -i0 -o0 -e0 tr '>' '\n' | stdbuf -i0 -o0 -e0 sed -rn 's/^.*\<([0-9]+)%\[.*$/\1/p' | zenity --progress --auto-close

对我来说至关重要的是stdbuf(1)


3
你能解释一下这条长代码的作用吗?如果你已经说过这不是“确切的答案”,那么这条代码与问题有什么关系? - Nico Haase
这与潜在的搜索方向有关,这就是我所说的;命令行以“C”语言环境运行wget,并使用参数使其以适合进一步处理(关闭I/O缓冲)的方式输出进度到zenity的进度条中 - 这导致了一种不错的GUI,例如某些下载助手。 - Michael Shigorin
1
请将以下与编程有关的内容从英语翻译成中文。仅返回翻译后的文字:请将所有说明添加到答案本身,而不是评论部分。 - Nico Haase
你能否更新你的回答? - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接