22

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 &?

3
  • @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 ?
    – Nitin4873
    Jun 14, 2013 at 19:28
  • 2
    As an aside, your quoting is wacky. for s in a b c; do foo "$s".txt; done
    – tripleee
    Jun 15, 2013 at 4:59
  • 1
    @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
    Jun 15, 2013 at 5:03

3 Answers 3

16

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
12

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
1
  • 2
    That's moderately useful, but does not disambiguate multiple processes with the same arguments.
    – tripleee
    Jun 15, 2013 at 5:09
1

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .