2

I'm currently writing a Bash script. I want to download a file while printing text. For example, consider this script:

echo -e "---------------------------"
echo -e "Your file downloading..." 
echo -e "---------------------------"
wget example.com/1gbfile

In the second echo each . should be printed successively every second till the download finishes. If the number of . becomes three, like this: ..., it should be reset to only one . and continue the loop.

4
  • So the built-in indicator by wget doesn't do the job for you? Nov 16, 2022 at 14:43
  • 1
    I think the OP is actually interested in creating a "spinner like" animation, like this: askubuntu.com/questions/623933/… Nov 16, 2022 at 14:46
  • 2
    Also stackoverflow.com/q/73723689/7552 Nov 16, 2022 at 15:08
  • @ArturMeinild Yea, we can call it like that. I'm gonna obfuscate my script because of some private things like download server. And wget shows the download server etc. So I wanted to make something cool like this.
    – Erikli
    Nov 16, 2022 at 15:51

1 Answer 1

4
Main script:

Create the following script as the source for your progress/bouncing bar (I called it bash-progress):

#!/bin/bash

# Initial configuration variables

# Set time interval for progress delay (in fraction of seconds)
time_delay=".2"

# Set left and right brackets (1 character)
  lb="["
#  lb="("
#  lb=" "
  rb="]"
#  rb=")"
#  rb=" "

# Function to show bouncing bar while running command in the background
show_bouncer() {
  # If no argument is given, then this is run on the last command - else provide PID
  if [[ -z $1 ]]
  then
    PID=$!
  else
    PID=$1
  fi
  ii=0
  # Define bouncer array (3 characters)
  bo=('.  ' '.. ' '...' ' ..' '  .' ' ..' '...' '.. ')
#  bo=('⠄  ' '⠂⠄ ' '⠁⠂⠄' '⠂⠂⠂' '⠄⠂⠁' ' ⠄⠂' '  ⠄' '   ')
#  bo=('⡇  ' '⣿  ' '⣿⡇ ' '⢸⣿ ' ' ⣿⡇' ' ⢸⡇' '  ⡇' '   ')
  # True while the original command is running
  while [[ -d "/proc/$PID" ]]
  do
    ch="${bo[(ii++)%${#bo[@]}]}"
    printf "%b" " ${lb}${ch}${rb}"
    sleep "$time_delay"
    # Adjust backspaces to bouncer length + 3
    printf "\b\b\b\b\b\b"
  done
}

The script can work in 2 ways: Either by using the PID of the last command run, or with a given PID. The most common use is with the last command.

Using it:

So you simply create your other script like this:

#!/bin/bash

# Include Bash progress bars - or include the entire source in your script.
source "./bash-progress"

your_command_here &
show_bouncer

It's important to run the command in the background, since it then moves on immediately to show the bouncer.

You can easily test it with a sleep command:

#!/bin/bash

# Include Bash progress bars - or include the entire source in your script.
source "./bash-progress"

sleep 5 &
show_bouncer
Bonus info:

To use with a PID other than the last one, you can use pgrep (-n for newest and -x for exact match) to find the latest instance of the process like this:

#!/bin/bash

# Include Bash progress bars - or include the entire source in your script.
source "./bash-progress"

your_command &
do_something_else
do_anything_meanwhile
show_bouncer $(pgrep -nx "your_command")
6
  • 1
    Really nice, simple and customizable script! Nov 17, 2022 at 9:29
  • 1
    Thanks. I have a slew of other variations, I think I'll put it on Gitlab when I get around to it, and link here. 😎 Nov 17, 2022 at 9:30
  • It works perfectly fine. Thank you so much! That's what I was looking for exactly!!
    – Erikli
    Nov 17, 2022 at 10:09
  • @ArturMeinild Umm, I'm sorry. I don't want to be sassy but how can I use it for the second echo? I tried to implement it but i screwed it up :/
    – Erikli
    Nov 17, 2022 at 10:14
  • I'm sorry, but if you want to implement it like that (where you're going to go back and redraw a specific area of the screen where you have already printed), then that's something you'll have to research yourself. My implementation is more "linear", so that the bouncing bar is the last thing that's printed while it waits. Nov 17, 2022 at 10:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .