You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shell脚本中获取timeout与tcpdump的两个Linux进程ID

获取timeout和tcpdump的进程ID的两种实现方法

方法一:利用GNU timeout的父子进程关系获取PID

原脚本中你拿到的是tcpdump的PID,可能是因为使用的timeout版本(比如busybox的timeout)默认会exec替换自身进程为tcpdump,导致两者PID相同。如果是GNU timeout,默认不会这么做,此时可以通过以下步骤获取两个PID:

#!/bin/bash

TIMEOUT_DURATION=3600
TIMEOUT=${v_TIMEOUT:-$TIMEOUT_DURATION}
FILTER=${v_FILTER:-} # 过滤器含特殊符号时需URI编码
FILENAME=$(date +%s).log

# 启动timeout后台进程,捕获timeout的PID
timeout "$TIMEOUT" tcpdump -i eth0 -w "$FILENAME" $FILTER > /dev/null 2>&1 &
TIMEOUT_PID=$!

# 短暂等待tcpdump启动完成,避免pgrep找不到进程
sleep 0.1

# 通过timeout进程的PID查找其子进程(tcpdump)的PID
TCPDUMP_PID=$(pgrep -P "$TIMEOUT_PID")

echo "TIMEOUT_PID=$TIMEOUT_PID"
echo "TCPDUMP_PID=$TCPDUMP_PID"

说明:

  • pgrep -P $TIMEOUT_PID会列出所有父进程ID为$TIMEOUT_PID的子进程,这里对应的就是tcpdump进程
  • 加入sleep 0.1是为了确保tcpdump完成启动初始化,避免因进程未就绪导致pgrep返回空

方法二:手动实现超时逻辑(通用兼容版本)

如果你的timeout版本存在进程替换问题,或者需要更通用的实现,可以自己用sleep和后台进程实现超时监控,这样能明确获取两个进程的PID:

#!/bin/bash

TIMEOUT_DURATION=3600
TIMEOUT=${v_TIMEOUT:-$TIMEOUT_DURATION}
FILTER=${v_FILTER:-}
FILENAME=$(date +%s).log

# 启动tcpdump后台进程,捕获其PID
tcpdump -i eth0 -w "$FILENAME" $FILTER > /dev/null 2>&1 &
TCPDUMP_PID=$!

# 启动一个后台监控进程,到达超时时间后杀死tcpdump
( sleep "$TIMEOUT" && kill "$TCPDUMP_PID" 2>/dev/null ) &
TIMEOUT_MONITOR_PID=$!

echo "TCPDUMP_PID=$TCPDUMP_PID"
echo "TIMEOUT_MONITOR_PID=$TIMEOUT_MONITOR_PID"

说明:

  • 这里的TIMEOUT_MONITOR_PID是负责超时逻辑的后台进程PID,你可以通过杀死它来取消超时机制
  • 如果提前手动杀死tcpdump,监控进程执行kill时会因进程不存在报错,2>/dev/null用于屏蔽该无意义错误

内容的提问来源于stack exchange,提问作者Yogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:27:05