Linux服务器一直有个TCP连上来发数据,跑到对应的机器上发现连接已经断了,对应的进程也退出了。估计是某种定时任务。

排查代码无果,只能通过命令行来监控。这里直接上ss命令

  while true; do pid=$(ss -tanpe state established 'dst 10.11.22.33:4455'  | awk 'match($0,/pid=([0-9]+)/,a){print a[1]}'); [[ -n $pid ]] && tr '\0' ' ' </proc/$pid/cmdline ; sleep 0.2; done;

解释下:

  1. while true; do ...; sleep 0.2; done;每0.2s反复刷新执行指定命令。
  2. ss -tanpe state established 'dst 10.11.22.33:4455'
    - -t 选项表示显示 TCP 连接。
    - -a 显示所有连接。
    - -n 不解析主机名、端口。
    - -p 显示进程信息。
    - -e 显示额外的详细信息。
    - state established TCP已连接
    - dst 10.11.22.33:4455 过滤TCP目标地址+端口
  3. awk 'match($0,/pid=([0-9]+)/,a){print a[1]}' 提取出 pid
  4. [[ -n $pid ]] && tr '\0' ' ' </proc/$pid/cmdline 从procfs读取该进程启动时的命令和参数。且把空字符 \0替换为空格

综合起来:不断地查询目标 IP 地址和端口的网络连接,找到与之相关的进程 ID,并显示该进程的命令行。每隔 0.2 秒刷新一次,持续监控这个连接对应的进程。

跑了一阵子,发现 $pid 可能有多行。囧,只能用双层 while 了:

  while true; do ss -tanp state established 'dport = 2333' | awk 'match($0,/pid=([0-9]+)/,m){print m[1]}' | while read -r pid; do echo $(date '+%F %T') $pid $(readlink -f /proc/$pid/cwd) $(tr '\0' ' ' </proc/$pid/cmdline); done ;  done;