启动并监视shell脚本中的进程以完成

时间:2012-08-03 12:15:20

标签: bash shell unix process

我有一个简单的shell脚本,它也在下面:

#!/usr/bin/sh

echo "starting the process which is a c++ process which does some database action for around 30 minutes"
#this below process should be run in the background
<binary name> <arg1> <arg2>

exit

现在我想要的是监控和显示流程的状态信息。 我不想深入了解它的功能。由于我知道该过程将在30分钟内完成,我想向用户显示每1分钟完成3.3%并且还检查过程是否在后台运行,最后如果过程完成我想要显示它完成了。

有人可以帮帮我吗?

3 个答案:

答案 0 :(得分:3)

你能做的最好的事情就是在你的应用中加入某种仪器, 并让它以work items processed / total amount of work为基础报告实际进度。

如果做不到这一点,你确实可以参考该事物已经运行的时间。

以下是我过去使用过的一个示例。适用于ksh93和bash。

#! /bin/ksh
set -u
prog_under_test="sleep"
args_for_prog=30

max=30 interval=1 n=0

main() {
    ($prog_under_test $args_for_prog) & pid=$! t0=$SECONDS

    while is_running $pid; do
        sleep $interval
        (( delta_t = SECONDS-t0 ))
        (( percent=100*delta_t/max ))
        report_progress $percent
    done
    echo
}

is_running() { (kill -0 ${1:?is_running: missing process ID}) 2>& -; }

function report_progress { typeset percent=$1
    printf "\r%5.1f %% complete (est.)  " $(( percent ))
}

main

答案 1 :(得分:1)

如果您的流程涉及管道而非http://www.ivarch.com/programs/quickref/pv.shtml将是一个很好的解决方案,或者替代方案是http://clpbar.sourceforge.net/。但这些基本上就像带有进度条的“猫”,需要一些东西来管理它们。有一个小程序,你可以编译,然后作为后台进程执行,然后在事情结束时终止,http://www.dreamincode.net/code/snippet3062.htm如果你只想显示30分钟的东西,然后打印几乎完成,那么可能会工作控制台,如果你的进程运行很长并且退出,但你必须修改它。可能更好的只是创建另一个shell脚本,在循环中每隔几秒显示一个字符并检查前一个进程的pid是否仍在运行,我相信你可以通过查看$$变量获取父pid然后检查是否它仍然在/ proc / pid中运行。

答案 2 :(得分:0)

你真的应该让命令输出统计信息,但为了简单起见,你可以做一些这样的事情来简单地在你的进程运行时增加一个计数器:

#!/bin/sh

cmd &  # execute a command
pid=$! # Record the pid of the command
i=0
while sleep 60; do
  : $(( i += 1 ))
  e=$( echo $i 3.3 \* p | dc )   # compute percent completed
  printf "$e percent complete\r" # report completion
done &                           # reporter is running in the background
pid2=$!                          # record reporter's pid
# Wait for the original command to finish
if wait $pid; then
    echo cmd completed successfully
else
    echo cmd failed
fi      
kill $pid2        # Kill the status reporter