【问题标题】:start and monitoring a process inside shell script for completion启动并监控 shell 脚本中的进程以完成
【发布时间】:2012-08-03 12:15:19
【问题描述】:

我有一个简单的 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% 并检查该过程是否在后台运行,最后如果该过程完成我想显示它已经完成了。

有人可以帮帮我吗?

【问题讨论】:

标签: bash shell unix process


【解决方案1】:

您能做的最好的事情就是在您的应用程序中加入某种仪器, 并让它以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

【讨论】:

  • 顺便说一句,(( ... ))function ... 语法都不是 POSIX,但 bash 和 ksh93 都支持它们。此外,ksh93 给出浮点结果。
【解决方案2】:

如果您的流程涉及管道,那么 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 中运行。

【讨论】:

    【解决方案3】:

    您确实应该让命令输出统计信息,但为简单起见,您可以执行以下操作来在进程运行时简单地增加一个计数器:

    #!/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
    

    【讨论】:

      猜你喜欢
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 2015-12-21
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多