Terminating a bash shell script running in the background

64,833

Solution 1

By default, ps will not show the parameters the program was called with. The options -f and -l both will show the full call.

ps -fu username

will result in output that looks like:

username 23464 66.7  0.0  11400   628 pts/5    R    15:28   1:40 bash script.sh

Solution 2

You have a couple of options. Since your process is running in the background, you can use jobs to find it:

nohup bash script.sh &
...
jobs
[1]+ Running    nohup bash script.sh &
kill %1
jobs
[1]+ Terminated nohup bash script.sh &

You can also use pkill to search the process table for a command line matching; viz:

pkill -f script.sh

Solution 3

The ps output (with e.g. ps aux) include the parent's process ID. Kill the parent bash, and its children, too, will be terminated.

For an ASCII visualization of the process tree, try pstree -p with a few background processes running.

Share:
64,833

Related videos on Youtube

eikonal
Author by

eikonal

Updated on September 18, 2022

Comments

  • eikonal
    eikonal over 1 year

    I often use bash shell scripts to run simple commands for many different files. For example, suppose that I have the following bash shell script, called script.sh, that runs the program/command foo on three text files "a.txt", "b.txt", "c.txt":

    #!/bin/bash
    
    for strname in "a" "b" "c"
    do
    foo $strname".txt"
    done
    

    Also, suppose that foo $strname".txt" is slow, so the execution of the script will take a long time (hours or days, for example). Because of this, I would like to use nohup so that the execution continues even if the terminal is closed or disconnected. I would also like the script to immediately go to the background, so I will use the & operator. Thus I will use the following command to call script.sh:

    nohup bash script.sh &
    

    This works fine for running the script in the background and without hangup, but now suppose that I would like to terminate the execution at some point for some reason. How can I do this?

    The problem that I have encountered is that, by looking at top, I see only the foo corresponding to "a.txt". I can terminate that foo call, but then the foo corresponding to "b.txt" gets called and then I have to terminate that one as well, and so on. For tens or hundreds of text files specified in the for loop, it becomes a pain to terminate every foo, one by one! So somehow I need to instead terminate the shell script itself, not the particular calls issued from the shell script.

    When I type the command

    ps -u myusername
    

    where myusername is my username, I get a list of processes that I'm running. But I see two different process IDs called bash. How do I know which of these processes, if any, corresponds to my original call nohup bash script.sh &?

    • nitin
      nitin almost 11 years
      @Andrew ,Do both of the process show nohup mentioned in the command ? .... alternatively you can try ps -aWu Andrew and check if you get a locate a single long entry with nohup .... does it help ?
    • tripleee
      tripleee almost 11 years
      As an aside, your quoting is wacky. for s in a b c; do foo "$s".txt; done
    • tripleee
      tripleee almost 11 years
      @NSD: No, the nohup will be long gone by the time you bring up a process listing to see the job you started. You can look at the "niceness" column in the ps output but the answers here are more useful.
  • tripleee
    tripleee almost 11 years
    That's moderately useful, but does not disambiguate multiple processes with the same arguments.