如何杀死 bash 脚本生成的所有子进程?

如何杀死 bash 脚本生成的所有子进程?

我有一个看起来像这样的脚本。调用方式为./myscript.sh start

#!/bin/bash
if [[ "$1" == "start" ]]; then
  echo "Dev start script process ID: $$"

  cd /my/path1
  yarn dev &> /my/path/logs/log1.log &
  echo "started process1 in background"
  echo "Process ID: $!"
  echo "Logging output at logs/log1.log"
  sleep 2

  cd /my/path2
  yarn start:dev &> /my/path/logs/log2.log &
  echo "started process2 in background"
  echo "Process ID: $!"
  echo "Logging output at logs/log2.log"
  sleep 2

  cd /my/path2
  yarn dev &> /my/path/logs/log3.log &
  echo "started process3 in background"
  echo "Process ID: $!"
  echo "Logging output at logs/log3.log"
elif [[ "$1" == "stop" ]]; then
  killList=`ps  | grep node | awk '{print $1}'`
  if [[ $killList != "" ]]; then
      echo $killList | xargs kill
      echo  "Processes killed: $killList"
  else
      echo "Nothing to stop"
  fi
else
  echo "Invalid argument"
fi

当我运行此脚本后运行时ps,我可以看到一堆我认为已由命令启动的节点进程(超过 3 个)yarn dev。我想运行./myscript.sh stop并停止我之前运行 ./myscript.sh start 生成的所有节点进程

我怎样才能做到这一点?

答案1

您可以获得进程列表直接地由此产生bash并发送给SIGTERM他们:

pgrep -P $$ --signal SIGTERM

$$是当前bash脚本的进程号。

根据子进程处理信号的方式,这可能会或不会杀死孙进程(等等,递归地)。

因此,另一种方法是列出从您开始的整个进程树bash,然后杀死它们。

pstree -A -p $$ | grep -Eow "[0-9]+" | xargs kill

pstree输出树(为人类格式化),grep提取进程号,然后对它们执行您需要执行的操作,例如kill为每个进程运行。

请注意,上面的行pstree还将列出grepxargs进程,因此您将收到No such process来自 的两个警告kill。不确定是否存在竞争条件,这只是概念证明。您可以对管道的右侧进行编码,以正确处理进程列表、过滤器等。

相关内容