I have the following in a script:
yes >/dev/null &
pid=$!
echo $pid
sleep 2
kill -INT $pid
sleep 2
ps aux | grep yes
When I run it, the output shows that yes is still running by the end of the script. However, if I run the commands interactively then the process terminates successfully, as in the following:
> yes >/dev/null &
[1] 9967
> kill -INT 9967
> ps aux | grep yes
sean ... 0:00 grep yes
Why does SIGINT terminate the process in the interactive instance but not in the scripted instance?
EDIT
Here's some supplementary information that may help to diagnose the issue. I wrote the following Go program to simulate the above script.
package main
import (
"fmt"
"os"
"os/exec"
"time"
)
func main() {
yes := exec.Command("yes")
if err := yes.Start(); err != nil {
die("%v", err)
}
time.Sleep(time.Second*2)
kill := exec.Command("kill", "-INT", fmt.Sprintf("%d", yes.Process.Pid))
if err := kill.Run(); err != nil {
die("%v", err)
}
time.Sleep(time.Second*2)
out, err := exec.Command("bash", "-c", "ps aux | grep yes").CombinedOutput()
if err != nil {
die("%v", err)
}
fmt.Println(string(out))
}
func die(msg string, args ...interface{}) {
fmt.Fprintf(os.Stderr, msg+"\n", args...)
os.Exit(1)
}
I built it as main and running ./main in a script, and running ./main and ./main & interactively give the same, following, output:
sean ... 0:01 [yes] <defunct>
sean ... 0:00 bash -c ps aux | grep yes
sean ... 0:00 grep yes
However, running ./main & in a script gives the following:
sean ... 0:03 yes
sean ... 0:00 bash -c ps aux | grep yes
sean ... 0:00 grep yes
This makes me believe that the difference has less to do on Bash's own job control, though I'm running all of this in a Bash shell.
yesterminates immediately with interactivekillbut stays running with the script.GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)- what shell and version do you have?