Shell 外壳程序脚本在父进程终止后未终止子进程

Shell 外壳程序脚本在父进程终止后未终止子进程,shell,jmeter,Shell,Jmeter,我有一个shell脚本(run.sh),它并行运行两个命令(jmeter脚本)。如果我终止shell脚本,它不会终止启动的并行进程,它们在后台运行 如果在执行run.sh的终端中按下Ctrl+C,我可以创建一个在Windows和Linux中都能工作的shell脚本并终止所有进程吗 #!/bin/sh JmeterFolder=$1 $JmeterFolder/bin/jmeter.bat -n -t one.jmx -j oneLog.log & $JmeterFolder/bin/

我有一个shell脚本(
run.sh
),它并行运行两个命令(
jmeter
脚本)。如果我终止shell脚本,它不会终止启动的并行进程,它们在后台运行

如果在执行
run.sh
的终端中按下Ctrl+C,我可以创建一个在Windows和Linux中都能工作的shell脚本并终止所有进程吗

#!/bin/sh

JmeterFolder=$1
$JmeterFolder/bin/jmeter.bat -n -t one.jmx -j oneLog.log & 
$JmeterFolder/bin/jmeter.bat -n -t two.jmx -j twoLog.log & 
wait
这是我的密码

我试过:

#!/bin/sh

trap 'stop' 2
stop()
{   
    kill -9 $pid1 $pid2
}

JmeterFolder=$1
$JmeterFolder/bin/jmeter.bat -n -t one.jmx -j oneLog.log & 
pid1=$! &
$JmeterFolder/bin/jmeter.bat -n -t two.jmx -j twoLog.log &
pid2=$! &
wait

但当我在Windows PowerShell中执行它时,它不起作用,我认为这不是一种正确的方法。

编写了一个无限循环来模拟您的Jeter: subtask.sh

#!/bin/bash
while true
do
  date -R
  sleep 1
done
启动子任务并睡眠100秒以等待Ctrl-C的主脚本:

#!/bin/bash

trap 'kill $subpid; exit' SIGINT
./subtask.sh  &
subpid=$!
sleep 100
结果:

$ ./main.sh 
Mon, 06 May 2019 02:03:32 -0700
Mon, 06 May 2019 02:03:33 -0700
^C$ 
当我按Ctrl-C“^C”时,它在打印两行后停止

如果主shell已结束,子任务的父进程ID将变为1,因此它无法再向后台进程传递信号


我认为解决方法只能是将子任务PID记录在一个文件中,并在想要结束它们时终止PID。

编写了一个无限循环来模拟Jeter: subtask.sh

#!/bin/bash
while true
do
  date -R
  sleep 1
done
启动子任务并睡眠100秒以等待Ctrl-C的主脚本:

#!/bin/bash

trap 'kill $subpid; exit' SIGINT
./subtask.sh  &
subpid=$!
sleep 100
结果:

$ ./main.sh 
Mon, 06 May 2019 02:03:32 -0700
Mon, 06 May 2019 02:03:33 -0700
^C$ 
当我按Ctrl-C“^C”时,它在打印两行后停止

如果主shell已结束,子任务的父进程ID将变为1,因此它无法再向后台进程传递信号


我认为解决方法只能是将子任务PID记录在一个文件中,并在想要结束它们时杀死PID。

是,也不是。你不能在
run.sh
中设置陷阱,即在后台简单地启动
jmeter
脚本,因为
run.sh
启动
jmeter
命令,然后退出,没有可接受的
ctrl+c
。如果删除
&
,进程将不再并行运行,但您可以拦截
ctrl+c
。最好让每个
jmeter
脚本创建一个包含其进程ID的运行文件和另一个脚本来处理捕获
ctrl+c
,然后读取运行文件并杀死两个PID。(还有,您是如何在POSIX shell中运行
.bat
文件的?)我的重点是
JmeterFolder/bin/jmeter.bat
(DOS批处理文件和POSIX shell是苹果和橙子)。所以我有点不清楚你打算如何混合它们?明白了,至于创建保存运行的
Jmeter
进程的pid的文件,看看这将提供创建保存每个
Jmeter
进程的pid的文件的基本方法,然后需要第三个脚本来监视
ctrl+c
(由于缺少更好的单词而使用的中断处理程序)这可以在两个PID上调用
kill
。您的父脚本对进程和出口进行后台处理这一事实有点问题。您的
等待
方法显示出了希望。以下是一些方法,您可以查看@RanadipDutta,谢谢。我通常会这样做,但在这里我并没有提供有效的解决方案,但更多地概述了问题这需要解决,并提供一些方法方面的线索。我必须坐下来亲自研究,以确保有一个可靠的解决方案。不过,现在我怀疑Charles或Ed会顺道来访,他们可以立即提供一个简洁的答案。(尽管在Linux和Windows上工作的要求可能也会让他们困惑
:)
是,也不是。您不能在
run.sh
中设置一个陷阱,它只是在后台启动
jmeter
脚本,因为
run.sh
同时启动
jmeter
命令,然后退出,没有任何东西可以接受
ctrl+c
。如果您删除
“&
,进程将不再运行并行运行,但您可以拦截
ctrl+c
。最好让每个
jmeter
脚本创建一个包含其进程ID的运行文件和另一个脚本来处理捕获
ctrl+c
,然后读取运行文件并杀死两个PID。(另外,您如何在POSIX shell中运行
.bat
文件?)我的重点是
JmeterFolder/bin/jmeter.bat
(DOS批处理文件和POSIX外壳是苹果和桔子).所以我有点不清楚你打算如何混合它们?明白了,至于创建保存正在运行的
Jmeter
进程的pid的文件,看看这将提供创建保存每个
Jmeter
进程的pid的文件的基本方法,然后需要第三个脚本来监视
ctrl+c
(由于缺少更好的单词而使用的中断处理程序)这可以在两个PID上调用
kill
。您的父脚本对进程和出口进行后台处理这一事实有点问题。您的
等待
方法显示出了希望。以下是一些方法,您可以查看@RanadipDutta,谢谢。我通常会这样做,但在这里我并没有提供有效的解决方案,但更多地概述了问题这需要解决,并提供一些方法方面的线索。我必须坐下来亲自研究,以确保有一个可靠的解决方案。不过,现在我怀疑Charles或Ed会顺道来访,他们可以立即提供一个简洁的答案。(尽管在Linux和Windows上工作的要求可能也会让他们困惑
:)
谢谢你的回答,但我没有安排运行,但是如果我按cntrl+cI,脚本应该能够停止它启动的所有进程。看,你的代码应该可以工作,我更新了上面的答案,请检查它是否与你的答案类似。谢谢你的回答,但我没有安排运行,而是脚本如果我按下cntrl+cI,应该能够停止它启动的所有进程。请看,看起来您的代码应该可以工作,我更新了上面的答案,请检查它是否与您的类似。