Home > OS >  How do I stop a scirpt running in the background in linux?
How do I stop a scirpt running in the background in linux?

Time:03-10

Let's say I have a silly script:

while true;do
  touch ~/test_file
  sleep 3
done

And I start the script into the background and leave the terminal:

chmod u x silly_script.sh
./silly_script.sh &
exit

Is there a way for me to identify and stop that script now? The way I see it is, that every command is started in it's own process and I might be able to catch and kill one command like the 'sleep 3' but not the execution of the entire script, am I mistaken? I expected a process to appear with the scripts name, but it does not. If I start the script with 'source silly_script.sh' I can't find a process by the name of 'source'. Do I need to identify the instance of bash, that is executing the script? How would I do that?

EDIT: There have been a few creative solutions, but so far they require the PID of the script execution to be stored right away, or the bash session to not be left with ^D or exit. I understand, that this way of running scripts should maybe be avoided, but I find it hard to believe, that any low privilege user could, even by accident, start an annoying script into the background, that is for instance filling the drive with garbage files or repeatedly starting new instances of some software and even the admin has no other option, than to restart the server, because a simple script can hide it's identifier without even trying.

CodePudding user response:

The jobs command will show you all running background jobs. You can kill background jobs by id using kill, e.g.:

$ sleep 9999 &
[1] 58730
$ jobs
[1]   Running                 sleep 9999 &
$ kill %1
[1]   Terminated              sleep 9999
$ jobs
$

58730 is the PID of the backgrounded task, and 1 is the task id of it. In this case kill 58730 and kill %1` would have the same effect.

See the JOB CONTROL section of man bash for more info.

When you exit, the backgrounded job will get a kill signal and die (assuming that's how it handles the signal - in your simple example it is), unless you disown it first.

That kill will propogate to the sleep process, which may well ignore it and continue sleeping. If this is the case you'll still see it in ps -e output, but with a parent pid of 1 indicating its original parent no longer exists.

You can use ps -o ppid= <pid> to find the parent of a process, or pstree -ap to visualise the job hierarchy and find the parent visually.

CodePudding user response:

With the help of the fine people here I was able to derive the answer I needed:
It is true, that the script runs every command in it's own process, so for instance killing the sleep 3 command won't do anything to the script being run, but through a command like the sleep 3 you can find the bash instance running the script, by looking for the parent process: So after doing the above, you can run ps axf to show all processes in a tree form. You will then find this section:

  18660 ?        S      0:00 /bin/bash
  18696 ?        S      0:00  \_ sleep 3

Now you have found the bash instance, that is running the script and can stop it: kill 18660 (Of course your PID will be different from mine)

  • Related