2012-08-03 24 views
4

我有一个简单的shell脚本,其也低于:启动和监控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分钟内完成,因此我想向用户展示3.3%每1分钟完成一次,并检查过程是否在后台运行,最后如果过程完成,我想要显示它已完成。

有人可以帮我吗?

+3

请参见[流程管理](HTTP ://mywiki.wooledge.org/ProcessManagement)。 – 2012-08-03 12:28:41

回答

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 
+0

顺便说一下,'((...))'和'function ...'语法都不是POSIX,但bash和ksh93都支持它们。另外,ksh93给出了浮点结果。 – 2012-08-06 09:12:05

1

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

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