2012-08-03 25 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