3

I know that wget have some options to display or not the progress bars.

I would like to display the wget transfer in a more short way, or.. a percent or something dynamic but not taking so much space like the classic wget output because i have to insert it into a script with already it's output.

My goal is to display to the user that the file is being downloaded, maybe even it's speed but not ruining too much the overall look of the script.

Important: My wget passages are inside an if then else script, so I have to retain the error detection functionality.

My script have a block that looks like:

if wget -O filename http://someurl then
    some_action
else
    some_other_action
fi

Can someone provide me some funny examples of customized progress data or bars with this refinements? Thank you ;)

  • If @meuh's answer works for you, i suggest submitting a wishlist bug-report to the wget developers asking for a simple percentage --progress type. or submit the bug report to your distro's wget package maintainers and ask them to forward it upstream. – cas Apr 2 '16 at 23:33
5

If you use the "dot" progress output style, which is something like this:

   500K .......... .......... .......... .......... ..........  2%  496K 91s

then you can pipe this (which is on stderr) into awk or similar and just print the "2%" field shown in the last-2 column.

wget ... --progress=dot -q --show-progress 2>&1 |
awk 'NF>2 && $(NF-2) ~ /%/{printf "\r %s",$(NF-2)} END{print "\r    "}'

This shows you the changing percent value on one line, which is cleared at the end.


To preserve the return code of wget for an if..else you can ask bash to make pipelines return the error code of any command that failed (instead of just the rightmost command) by setting in the script:

set -o pipefail

Alternatively, you could put all of the if..else..fi code unchanged inside a block and pipe the stderr at the end into a single more informative awk such as suggested by cas in the comments:

( if wget ...
  fi
  if wget ...
  fi
  if wget ...
  fi
) 2>&1 | awk '
/^Saving to:/ { fn = gensub(/^Saving to: /,"",1) }
NF>2 && $(NF-2) ~ /%/ { printf "\r%s %s",fn,$(NF-2) }
END { gsub(/./," ",fn); print "\r    " fn }'

or to avoid missing important error messages on stderr, just redirect the stderr on each wget command to a 3rd file descriptor:

( if wget ... 2>&3
  then ... else ... fi
  if wget ... 2>&3
  then ... else ... fi
  if wget ... 2>&3
  then ... else ... fi
) 3>&1 | awk ...
  • +1. Here's a version that prints the filename with the percentage: wget ... | awk '/^Saving to:/ {fn=gensub(/^Saving to: /,"",1)}; NF>2 && $(NF-2) ~ /%/{printf "\r%s %s",fn,$(NF-2)} END{gsub(/./," ",fn); print "\r "fn} (there should be 4 spaces after \r, not just 1) – cas Apr 2 '16 at 23:31
  • While I am aware of the possibility of piping the output inside another command to a further refine I was wondering: Doesn't this break the capability of wget of returning the status? I have inside my code an if block like: if wget .. then .. something .. else .. fi and I fear that piping the command will break the "if block" functioning. – user3450548 Apr 3 '16 at 8:51
  • with bash there are methods to get that return code. eg set -o pipefail will make pipelines return the error code of any command that failed in it. – meuh Apr 3 '16 at 8:55
  • @meuh I see, added the requirement inside the question, can you edit the answer covering these more cases? I was thinking that with sed you can pratically completely rewrite the output but is something doable only if you keep the error detection working.. – user3450548 Apr 3 '16 at 9:48
  • @user3450548 I updated my answer with some ideas. – meuh Apr 3 '16 at 12:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.