1

I have a shell script (run.sh) that runs two commands (jmeter scripts) in parallel. If I terminate the shell script it is not killing the parallel process that got initiated, and they are running in background.

Can I make a shell script that would work in both Windows and Linux and will terminate all the process if Ctrl+C is pressed in the terminal that is executing run.sh?

#!/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

This is my code.

I have tried:

#!/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

but this is not working when I execute it in Windows PowerShell, and don't think this is a right approach.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
venkat sai
  • 455
  • 9
  • 30
  • 1
    Yes, and no. You can't set a trap in the `run.sh` that is simply starting both `jmeter` scripts in the background, because `run.sh` launches both `jmeter` commands and then exits, there is nothing to accept the `ctrl+c`. If you remove the `'&'`, the processes will no longer run in parallel, but you can intercept the `ctrl+c`. Better to have each of the `jmeter` scripts create a run-file containing their process ID and another script to handle trapping `ctrl+c` and then read the run files and kill both PIDs. (also, how are you running a `.bat` file in POSIX shell?) – David C. Rankin May 06 '19 at 06:21
  • this is a .sh file not a bat file, so i believe i can run it both in windows (using powershell) and linux I appreciate the comment and will try out the approach – venkat sai May 06 '19 at 06:25
  • 1
    I was focusing on `JmeterFolder/bin/jmeter.bat` (DOS batch files and POSIX shell are apples and oranges). So I'm a bit unclear in how you plan to mix them? – David C. Rankin May 06 '19 at 06:25
  • oh that is just jmeter sorry no .bat, my mistake – venkat sai May 06 '19 at 06:27
  • 1
    Got it, as far as creating files holding the pid of the running `Jmeter` processes, have a look at [Quick-and-dirty way to ensure only one instance of a shell script is running at a time](https://stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-running-at) That will provide the basic approach to creating files holding the PID of each `Jmeter` process, then you will need a third script to monitor for `ctrl+c` (an interrupt handler for lack of better words) that can call `kill` on both PIDs. – David C. Rankin May 06 '19 at 06:31
  • 1
    The fact your parent script backgrounds the processes and exits is a bit of a problem. Your `wait` approach shows promise. Here are some approaches you may look at [How do I kill background processes / jobs when my shell script exits?](https://stackoverflow.com/questions/360201/how-do-i-kill-background-processes-jobs-when-my-shell-script-exits) – David C. Rankin May 06 '19 at 06:35
  • @DavidC.Rankin . Completely agreed. I would suggest you to move your comments to a formulated answer which can help for future reference as well. – Ranadip Dutta May 06 '19 at 06:56
  • 1
    @RanadipDutta, thanks. I would normally do so, but here I didn't really provide a working solution, but more outlined the issues that would need to be addressed and a few leads on approaches to take. I'd have to sit down and work through it myself to ensure a robust solution. Now, however I suspect Charles or Ed will drop by and they can provide a succinct answer off the cuff. (though the requirement for working on Linux and Windows will likely puzzle them as well `:)` – David C. Rankin May 06 '19 at 07:20
  • Okie. Yes, I am expecting Ed to reply on it surely. – Ranadip Dutta May 06 '19 at 07:35
  • You're mixing 3 entirely different things in your question. The 2 code snippets in your question are Bourne-compatible shellscripts. `jmeter.bat` is apparently a Windows batch script. And you said you tried to invoke the shellscript in PowerShell on Windows (which cannot work). Contrary to your belief PowerShell does not run Bourne-compatible shellscripts. – Ansgar Wiechers May 06 '19 at 08:39

1 Answers1

0

Wrote an infinite loop to simulate your jemter: subtask.sh

#!/bin/bash
while true
do
  date -R
  sleep 1
done

Main script to start the substask and sleep 100 seconds to wait for Ctrl-C:

#!/bin/bash

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

result:

$ ./main.sh 
Mon, 06 May 2019 02:03:32 -0700
Mon, 06 May 2019 02:03:33 -0700
^C$ 

When I press Ctrl-C "^C", it stopped after printing two lines.

If the main shell has been ended, the subtask's parent process ID will become 1, so it cannot pass signal to background process anymore..

I think the workaround can only be record the subtask PID in a file, and kill pid when you want to end them..

Rong Zhao
  • 318
  • 1
  • 16
  • Thank you for the answer but i am not scheduling the run, but the script should be capable enough to stop all the process that it has started if i press cntrl+c – venkat sai May 06 '19 at 08:53
  • I see, looks like your code should work, I updated my answer above, please check if it is similar with yours. – Rong Zhao May 06 '19 at 09:08