ps だけで「gatling で grep されるプロセス(=コマンドラインに gatling を含む)」を全件拾って、各PIDの情報を出力するスクリプト

#!/usr/bin/env bash
set -euo pipefail

PATTERN="${1:-gatling}"

echo "=== dump processes matched by pattern: '${PATTERN}' ==="
echo "NOW: $(date -Is)"
echo "CURRENT SHELL PID: $$"
echo "CURRENT SHELL ulimit -n: $(ulimit -n 2>/dev/null || echo 'N/A')"
echo

# psだけでPIDを抽出(grepを使わずawkでフィルタ)
# ※コマンドライン全体に PATTERN が含まれる行を拾う
mapfile -t PIDS < <(
  ps -eo pid,args \
  | awk -v pat="$PATTERN" 'BEGIN{IGNORECASE=1}
      $0 ~ pat && $0 !~ /awk -v pat=/ && $0 !~ /dump_gatling_procs/ {print $1}
    ' \
  | awk 'NF{print}' \
  | sort -n | uniq
)

if [[ ${#PIDS[@]} -eq 0 ]]; then
  echo "No process matched."
  exit 0
fi

echo "Matched PIDs: ${PIDS[*]}"
echo

for pid in "${PIDS[@]}"; do
  # ここは「必ず1件分は出す」ため、procが消えてても落とさない
  if [[ ! -d "/proc/$pid" ]]; then
    echo "============================================================"
    echo "PID: $pid (already exited)"
    echo
    continue
  fi

  echo "============================================================"
  echo "PID: $pid"

  user="$(ps -o user=  -p "$pid" 2>/dev/null | awk '{$1=$1;print}' || true)"
  ppid="$(ps -o ppid=  -p "$pid" 2>/dev/null | awk '{$1=$1;print}' || true)"
  lstart="$(ps -o lstart= -p "$pid" 2>/dev/null | awk '{$1=$1;print}' || true)"
  cmd_ps="$(ps -o args=  -p "$pid" 2>/dev/null | awk '{$1=$1;print}' || true)"

  echo "USER: ${user:-N/A}"
  echo "PPID: ${ppid:-N/A}"
  echo "START: ${lstart:-N/A}"

  cmd_proc="$(tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null | sed -e 's/[[:space:]]\+/ /g' -e 's/[[:space:]]*$//')"
  if [[ -n "$cmd_proc" ]]; then
    echo "CMDLINE(/proc): $cmd_proc"
  else
    echo "CMDLINE(ps): ${cmd_ps:-N/A}"
  fi

  echo -n "LIMITS: "
  if [[ -r "/proc/$pid/limits" ]]; then
    awk '/Max open files/ {print $0}' "/proc/$pid/limits" || true
  else
    echo "N/A (no permission?)"
  fi

  # FD数
  if [[ -d "/proc/$pid/fd" ]]; then
    fd_count="$(ls -1 "/proc/$pid/fd" 2>/dev/null | wc -l | awk '{$1=$1;print}' || true)"
    sock_count="$(
      ls -l "/proc/$pid/fd" 2>/dev/null \
      | awk '{print $NF}' \
      | awk 'BEGIN{c=0} /^socket:\[/{c++} END{print c+0}'
    )"
    echo "OPEN_FD_COUNT: ${fd_count:-N/A}"
    echo "SOCKET_FD_COUNT: ${sock_count:-N/A}"
  else
    echo "OPEN_FD_COUNT: N/A"
    echo "SOCKET_FD_COUNT: N/A"
  fi

  # 親子ツリー
  if command -v pstree >/dev/null 2>&1; then
    echo "PSTREE:"
    pstree -ps "$pid" 2>/dev/null || echo "  (pstree failed / no permission)"
  else
    echo "PSTREE: (pstree not installed)"
  fi

  # ss の行数(grepを使わずawkで数える:該当なしでも0で返す=落ちない)
  if command -v ss >/dev/null 2>&1; then
    conn_lines="$(
      ss -antp 2>/dev/null \
      | awk -v pid="$pid" 'index($0, "pid="pid",")>0 {c++} END{print c+0}'
    )"
    echo "SS_CONNECTION_LINES: ${conn_lines:-0}"
  fi

  echo
done

コメント

タイトルとURLをコピーしました