如何在 shell 中的多个进程下获得正确的尾部 PID

How to get correct tail PID under multiple process in shell

我正在实现 monitor_log 函数,它将跟踪 运行 日志中的最新行并使用 while 循环检查所需的字符串,超时逻辑应该是在跟踪日志 运行 时超过 300 秒,它必须关闭尾部和 while 循环管道。参考,如前所述,即使monitor_log函数完成,它会在后台留下tail进程,所以我必须手动杀死它以防万一数百次调用 monitor_log 将留下数百个 tail 进程。

下面的函数monitor_log kill correct tail PID 只在单进程情况下,因为tail_pid=$(ps -ef | grep 'tail' | cut -d' ' -f5)会return正确 tail PID 上唯一的进程。当遇到多进程情况(process fork),比如monitor_log函数多次调用parallel tail log,会出现多个tail进程运行,tail_pid=$(ps -ef | grep 'tail' | cut -d' ' -f5)不是能够 return 恰好 tail 属于当前 fork 的 PID。

那么在 monitor_log 功能完成时 NOT 是否可以离开 tail 进程?或者如果离开 tail 进程,是否有正确的方法找到它的 正确的 PID(不是来自其他线程的 tail PID)并在多进程情况下杀死它?

function monitor_log() {
  if [[ -f "running.log" ]]; then
    # Tail the running log last line and keep check required string
    while read -t 300 tail_line
    do
      if [[ "$tail_line" == "required string" ]]; then
        capture_flag=1
      fi
      if [[ $capture_flag -eq 1 ]]; then
        break;
      fi
    done < <(tail -n 1 -f "running.log")
    # Not get correct tail PID under multiple process
    tail_pid=$(ps -ef | grep 'tail' | cut -d' ' -f5)
    kill -13 $tail_pid
  fi
}

您可以试试下面的代码:

function monitor_log() {
  if [[ -f "running.log" ]]; then
    # Tail the running log last line and keep check required string
    while read -t 300 tail_line
    do
      if [[ "$tail_line" == "required string" ]]; then
        capture_flag=1
      fi
      if [[ $capture_flag -eq 1 ]]; then
        break;
      fi
    done < <(tail -n 1 -f "running.log")

     tailpid=$!

     kill $tailpid
  fi
}

> $!在后台

中给出最后一个作业 运行 的进程 ID (PID)

更新:这将杀死触发尾巴的子外壳,如评论中所建议的那样

另一种方法可能是将超时添加到 tail 命令,如下所示:

timeout 300s tail -n 1 -f "running.log"