Shell – Display wget transfer in a more compact way (while keeping the error detection functionality)

shell-scriptwget

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 😉

Best Answer

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 ...
Related Question