【问题标题】:Portable shell solution to check if PID is zombied用于检查 PID 是否为僵尸的便携式 shell 解决方案
【发布时间】:2013-09-25 00:39:51
【问题描述】:

我想检查一个 PID 是否正在运行(即存在并且没有被僵尸化)。

/proc/$PID/stat 开始确实很快,但我想要更便携的东西。

我现在最好的是:

( STAT="$(ps -ostat= -p$PID)"; test "$STAT" -a "$STAT" "!=" "Z" )

这似乎适用于 BSD 和 Linux。有没有更好的办法?

【问题讨论】:

  • 如果你发现一个僵尸,你的计划是什么?您可以简单地查看kill -0 $PID 是成功还是失败,尽管失败可能意味着$PID 是僵尸或者没有这样的进程。不过,除非您是操作系统,否则我不确定这是一个有用的区别。
  • @chepner kill -0 在僵尸上返回 0(与正在运行的进程相同)
  • stat -o 选项的参数在 POSIX 2008 中没有描述。所以你的代码 sn-p 也不可移植((+1 有趣的问题
  • @gavenkoa ps-o 选项2013 edition中描述的
  • 这应该更符合 POSIX:! ps $PID |awk 'NR == 2 {exit ($3 == "Z")}' -- awk 命令查看第二行(第一行是标题)并在第三列 (STAT) 为“Z”时退出 true , 然后取反 (!),这样 Z 统计数据或无效 PID 将返回 false,而任何其他统计数据将返回 true。

标签: shell unix sh pid


【解决方案1】:

希望符合 POSIX。用破折号测试。要使用它,请使用您喜欢的编辑器保存它,使其可执行 (chmod 755 foo.sh),然后使用 PID 参数运行它。

当然你可以根据需要进行调整。

#!/bin/sh
pid="$1";
psout=$(ps -o s= -p "$pid");
pattern='[SRDTWX]';

case "$psout" in 
    $pattern) echo "Not a zombie";;
    Z) echo "Zombie found";;
    *) echo "Incorrect input";; 
esac

【讨论】:

  • 为什么使用 bash-only 正则表达式而不是 POSIX sh case-statement 模式匹配?
  • 我当然不反对 POSIX sh 解决方案,这正是我所熟悉的。我确实在bash --posix 模式下尝试过,它仍然有效。我错过了什么吗?我意识到 posix 模式下的 bash 并不完美。
  • [[ ]] 非常非 POSIX,=~ 更是如此。就此而言,使用== 也是如此; POSIX 测试中的字符串比较运算符是 =,尽管大多数接近基线的 shell 和外部测试实现仍然将 == 实现为一种便利功能,因为它非常便宜。
  • 无论如何——case $psout in [SRDTWX]) echo "Not a zombie" ;; Z) echo "Zombie found" ;; *) echo "Incorrect input" ;; esac 可以说更易读也更短。
  • (顺便说一句,为了便于阅读,我倾向于建议将您的建议扩展到多行;折叠成单行很容易——您甚至可以将;s 留在如果你想让它变得特别简单)。
【解决方案2】:

恕我直言,解析“ps”的输出是最便携的方式。所有的 'ps' 变体在语法上都有一点不同,但整体输出足够好:

#!/bin/sh

process_show()
{
  ps
  ps ax
}

pid_is_zombie()
{
  pid="$1"

  process_show | while read -r LINE; do
    # e.g.: 31446 pts/7    R+     0:00 ps ax
    set -f
    set +f -- $LINE

    test "$1" = "$pid" || continue
    case "$3" in *'Z'*) return 0;; esac
  done

  return 1
}

pid_is_zombie 123 && echo "yes it is"

即使是“ps ax”也不是无处不在,所以我们必须尝试“ps”和“ps ax”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 2015-04-06
    • 2016-04-05
    • 2019-09-21
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多