如何检测并停止在后台调用自身并退出的脚本

如何检测并停止在后台调用自身并退出的脚本

我正在为一个工具编写一个包装脚本。包装器脚本应该准备环境,然后在后台调用该工具,然后退出。它看起来像这样:

#!/bin/bash
export FOO=1
tool "$@" &

这里没什么了不起的。除了我错误地没有调用该工具(/usr/bin/tool),而是有效地调用了包装器脚本本身(~/bin/tool)。不知不觉中我运行了包装脚本,但什么也没发生。至少没有任何可见的东西。

我想知道为什么什么也没发生。再次打开脚本。查看错误(未调用 /usr/bin/tool)。修复它以运行实际工具并保存。突然,这个工具弹出来了。经过一番思考后,我意识到包装器脚本正在后台一遍又一遍地运行。当我编辑脚本以调用实际工具时,脚本的下一次调用立即调用该工具并停止链。

因为它不分叉,所以不是分叉炸弹。但这似乎是一个递归幽灵。我重新创建了静默递归包装器并尝试检测。我的知识有限。我不是大师。我尝试过 ps 和 pgrep 等工具。我给这个脚本起了一个朗朗上口的名字:pgrep。但 pgrep 大多数时候什么也看不到。在循环中运行 pgrep 有时会捕获失控的脚本。大约每十秒一次?我没有做统计。

递归幽灵脚本是良性的。几乎不吃任何资源。也许唯一可见的效果是它导致 PID 快速升高。因为每次新的调用都会得到一个新的 PID。

如何检测并阻止在后台调用自身并退出的失控递归幽灵脚本?

以下是如何重现:

  1. 创建woop使用以下内容调用的脚本

     #!/bin/sh
     ./woop &
    
  2. 打开两个终端并在文本编辑器中打开脚本

  3. 在一个终端运行./woop。注意没有任何可见的事情发生。它将立即返回提示。

  4. 在第二个终端运行while true; do pgrep -fa woop; done。大约每十秒看到一个结果。

  5. 在文本编辑器中将行更改./woop &./woops &或其他内容并保存。注意第一个终端的错误 ( ./woop: line 2: ./woops: No such file or directory)

  6. 在第二个终端中通知不再找到任何结果。

答案1

使用forkstat如果可用的话应该可以很好地指示是否有任何进程正在运行。例如:

forkstat -e fork

当确定后,执行以下一项或全部操作:

  • chmod -x /path/to/file
  • mv ...
  • rm ...

可以选择使用该-S标志(这里是简化的统计数据):

$ forkstat -S
... loads of lines
^C
 Fork     Exec     Exit  ...   Total Process
11546    11532    11547  ...   34625 /bin/bash - ./woop
...

有关的:


相关内容