为什么(nohup'ed)脚本需要休眠才能让 `ps -ef` 工作?

为什么(nohup'ed)脚本需要休眠才能让 `ps -ef` 工作?

在包含以下行并由 ansible 调用(通过 ssh,然后 sudo)的脚本中,大约五分之四,我最终进入 if 分支,尽管我正在尝试ps并且grep正在永久运行该进程。在这种情况下回Count:显的是“0”。

PROC=[a]sdf # brackets, so we don't grep the grep process itself
# sleep 0.1
PID=(`ps -ef|grep -E "$PROC"|awk '{print $2}'`)
PIDLEN=`echo "${#PID[@]}"`

if [ "PIDLEN" -ne 1 ]; then
    echo \"$PROC\" does not designate a single, unique process. Count: "$PIDLEN"

现在有趣的是,当我取消注释“sleep 0.1”行时,我永远不会进入 if 分支,这正是我所期望的。

这个脚本是使用nohup以分离模式启动的,这可能是相关的。该剧本看起来像这样:

- shell:
    cmd: nohup ./script.sh </dev/null >/tmp/out 2>/tmp/err &

更新

与我的问题无关,但评论中有人似乎认为这pgrep总是比ps|grep组合更好。只是为了证明情况不一定如此 - 这实际上是我在这里不使用 pgrep 的原因 - 在 debian 10 中尝试这个:

$ sleep 1000 $(seq 1 1200)|wc -c&
[1] 13821
$ ps -ef|grep [1]200|wc -l
1
$ pgrep -f 1200|wc -l
0
$ pgrep -f 1038|wc -l
1
$ pgrep -f 1039|wc -l
0
$ pgrep -af 1038|wc -c
4102 # 5-digit PID + SPACE + 4096 chars
$ ps -ef|grep [1]200|wc -c
4952

这表明 pgrep greps/prints 每个进程仅打印 4096 个字符,而 ps -ef 则不止于此。 (显然 ps|grepping 获取数字通常不是一件安全的事情,我只是用它来证明这一点。)

使用此 Dockerfile 的任何人都可以轻松验证以上所有内容:

FROM debian:10
RUN apt-get clean
RUN apt-get update
RUN apt-get install -y --no-install-recommends procps

可以使用这些命令构建和运行

docker build -t debian10-pgrep-vs-ps .
docker run --rm -it debian10-pgrep-vs-ps

相关内容