【发布时间】:2019-12-27 21:46:34
【问题描述】:
我正在实现monitor_log 函数,该函数将从运行日志中跟踪最新行并使用while循环检查所需的字符串,超时逻辑应该是当tail log运行超过300秒时,它必须关闭tail和while循环管道。参考How to timeout a tail pipeline properly on shell,上面提到即使monitor_log函数完成,它会在后台留下tail进程,所以我必须手动杀死它,以防数百次调用monitor_log会离开数百个tail 进程。
下面的函数monitor_log 杀死正确的tail PID 仅在单进程情况下,因为tail_pid=$(ps -ef | grep 'tail' | cut -d' ' -f5) 将返回正确的tail PID,它在唯一的进程上。当遇到多进程情况(进程fork),例如多次调用monitor_log函数并行tail log,会有多个tail进程在运行,tail_pid=$(ps -ef | grep 'tail' | cut -d' ' -f5)不能准确返回tail所属的PID到当前的分叉。
那么当monitor_log 函数完成时,有可能不离开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
}
【问题讨论】:
-
您的问题具有误导性 - bash 脚本中没有“多线程”。 Shell 脚本是关于进程分叉的。 Ofc 可以并行运行(多处理!= 多线程)
-
好的,这是一个很好的建议,“多线程”是用于描述这里案例的错误术语,因为我对脚本的嵌入式机制有点新,让我更新为“进程分叉”跨度>
-
也许将其称为“在后台并行运行多个调用” - 然后它会自动清除您想要实现的目标。
-
是的,混蛋,还在检查它,感谢您的建议
标签: linux bash shell process fork