Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I display a progress indicator function in a shell script?

Tags:

shell

I want to write a progress indicator function within my script that loops a "please wait" message until the task that called it is done.

I want it to be a function so that I may reuse it in other scripts.

In order to achieve that, the function needs to be loosely coupled with other functions, i.e, the function calling it doesn't have to know its inner code.

Here's what I have so far. This function receives the pid of the caller and loops until the task is finished.

function progress() {
  pid="$1"

  kill -n 0 "${pid}" &> /dev/null && echo -ne "please wait"
  while kill -n 0 "${pid}" &> /dev/null ; do
    echo -n "."
    sleep 1
  done
}

it works fine when you use it in a script, such as:

#imports the shell script with the progress() function
. /path/to/progress.sh

echo "testing"
# $$ returns the pid of the script.
progress $$ &
sleep 5
echo "done"

output:

$ testing
$ please wait.....
$ done

The problem is when I call it from another function, as functions do not have pids:

function my_func() {
  progress $$ &
  echo "my func is done"
}

. /path/to/progress.sh
echo "testing"
my_func
sleep 10
echo done

output:

$ testing
$ please wait.....
$ my func. is done.
$ ..........
$ done
like image 366
Tarek Avatar asked Oct 04 '22 22:10

Tarek


1 Answers

You might be interested in the dialog - bash curses oriented menu system.

For the progress bar you can check the http://bash.cyberciti.biz/guide/A_progress_bar_(gauge_box)

or, another simpler project: http://www.theiling.de/projects/bar.html

if not interested, you can try the next:

dotpid=
rundots() { ( trap 'exit 0' SIGUSR1; while : ; do echo -n '.' >&2; sleep 0.2; done) &  dotpid=$!; }
stopdots() { kill -USR1 $dotpid; wait $dotpid; trap EXIT; }
startdots() { rundots; trap "stopdots" EXIT; return 0; }

longproc() {
    echo 'Start doing something long... (5 sec sleep)'
    sleep 5
    echo
    echo 'Finished the long job'
}

run() {
    startdots
    longproc
    stopdots
}

#main
echo start
run
echo doing someting other
sleep 2
echo end of prog
like image 70
jm666 Avatar answered Oct 12 '22 10:10

jm666