5

我想在我的脚本中编写一个进度指示器函数,循环“请稍候”消息,直到调用它的任务完成。

我希望它成为一个函数,以便我可以在其他脚本中重用它。

为了实现这一点,该函数需要与其他函数松散耦合,即调用它的函数不必知道其内部代码。

这是我到目前为止所拥有的。该函数接收调用者的 pid 并循环直到任务完成。

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
}

当您在脚本中使用它时它可以正常工作,例如:

#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"

输出:

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

问题是当我从另一个函数调用它时,因为函数没有 pid:

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

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

输出:

$ testing
$ please wait.....
$ my func. is done.
$ ..........
$ done
4

4 回答 4

2

您可能对dialog-bash curses 导向的菜单系统感兴趣。

对于进度条,您可以查看http://bash.cyberciti.biz/guide/A_progress_bar_(gauge_box)

或者,另一个更简单的项目: http ://www.theiling.de/projects/bar.html

如果不感兴趣,可以尝试下一个:

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
于 2013-06-04T20:35:57.280 回答
1

通过在后台运行它,您可以将其输出与其余代码混合在一起,因此在运行时您不得在其他地方输出任何内容progress

要将其实现为函数,您需要一个全局变量来控制进度何时终止(您可以将变量的名称作为 arg 传递给progress调用它时)。

于 2013-06-04T20:05:51.450 回答
1

我听说过这个项目。我没有用过它,所以不确定集成起来有多容易,但你可以读一读。

于 2013-06-04T20:06:25.020 回答
0

可悲的是,我无法使用 shell 脚本做我想做的事。这是我所做的:

function progress() {
  echo -ne "please wait"
  while :
  do
    echo -n '.'
    sleep 1
  done
}

用法:

aguarde &
dotpid=$!
# code
eval "kill ${dotpid}"
于 2013-06-28T17:56:12.733 回答