LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 12-23-2011, 07:23 PM   #1
wahoodoss
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Rep: Reputation: Disabled
Capturing PID's when the "tee" command is involved.


I have a Java GUI that starts a bash script that controls the running of other bash scripts, executes some system commands (e.g. cp and tar), and runs some executables. I want to add a "Stop" button that will kill all processes started by the aforementioned bash script. I know how to get the process IDs; the bash scripts are "echo'ing" $$ and the Java program is capturing that and killing those processes. Unfortunately, some of the scripts run cp's and other executables that won't die right away (e.g. the cp command is doing large copies). They will die eventually but I want to kill them now . While figuring out how to get the PID's of these commands, I came across an issue when the "tee" command is involved.

Here is an illustration of what I'm talking about:

When I run the following bash script, bbb.sh, which starts an external program, bbb.java:

Code:
#!/bin/bash
java bbb &
BBB_PID=$!
echo -e "BBB_PID ${BBB_PID}\n"
ps -a
This is what I see:

> bbb.sh
BBB_PID 10378

PID TTY TIME CMD
6720 pts/1 00:00:26 bluefish
10377 pts/1 00:00:00 bbb.sh
10378 pts/1 00:00:00 java
10379 pts/1 00:00:00 ps
I capture, via BBB_PID=$!, the PID of the java program. If killing PID 10377 doesn't kill the java program right away, then I can kill -9 10378 to finish off the java program.

Sometimes, though, the "tee" command is involved in the bash script and I notice the following:

Suppose now bbb.sh is as follows and I run it:

Code:
#!/bin/bash
java bbb | tee > out.txt &
BBB_PID=$!
echo -e "BBB_PID ${BBB_PID}\n"
ps -a
This is what I see:

> bbb.sh
BBB_PID 10397

PID TTY TIME CMD
6720 pts/1 00:00:27 bluefish
10395 pts/1 00:00:00 bbb.sh
10396 pts/1 00:00:00 java
10397 pts/1 00:00:00 tee
10398 pts/1 00:00:00 ps
In this case, the PID captured by BBB_PID=$! is that of the "tee" command not the "java bbb" command. This makes sense because, if I understand things correctly, $! contains the PID of the most recent background process, which in this case would be the "tee" command.

Now I can kill PID 10397, which causes PID 10396 to die with a pipe broken error. My concern is whether or not this is an okay thing to do. I have a bad feeling that this is not safe and may cause the whole process to crash.

I also noticed that everytime I tested this, the PID of the "tee" command was one greater than the PID of the "java bbb" command. If that is always going to be the case, then I could just kill the BBB_PID-1. But is that always going to be the case?

Any comments or suggestions?

Thanks times a million,
Bill
 
Old 12-24-2011, 04:50 AM   #2
War3zWad|0
Member
 
Registered: Sep 2011
Location: Houston, TX
Distribution: openSuSE, Fedora, CentOS, Debian,, and others
Posts: 84

Rep: Reputation: Disabled
if you know the commands that you are running from the bash prompt/s that you are creating with Java, the easiest way to get the info you are wanting would be to use something along these lines:

Code:
ps auxf|grep "command"|awk '{print $2}'


as an example:
1000     17799  0.0  0.0   4508  1368 ?        S    02:54   0:00 /bin/sh /usr/bin/firefox http://www.linuxques
1000     17807  5.8  3.5 410304 100120 ?       Sl   02:54   0:15  \_ /usr/lib/firefox/firefox-bin http://www.l
1000     17833  0.0  0.4  62144 13612 ?        S    02:54   0:00      \_ /usr/lib/mozilla/kmozillahelper
1000     17837  0.0  0.4  65668 11504 ?        Sl   02:54   0:00      \_ /usr/lib/firefox/plugin-container /us
1000     17849  0.4  0.5  68652 14596 ?        Sl   02:54   0:01          \_ /usr/lib/nspluginwrapper/i386/lin
1000     17927  1.0  1.6 138668 47040 ?        Rl   02:56   0:01 kdeinit4: konsole [kdeinit]                 
1000     17929  0.0  0.0   5292  2520 pts/0    Ss   02:56   0:00  \_ /bin/bash
1000     17967  0.0  0.0   2744   868 pts/0    R+   02:58   0:00  |   \_ ps auxf
1000     17938  0.0  0.0   5292  2340 pts/2    Ss   02:56   0:00  \_ /bin/bash
1000     17956  0.0  0.0   4484  1008 pts/2    S+   02:58   0:00      \_ screen
1000     17957  0.0  0.0   4484  1076 ?        Ss   02:58   0:00          \_ SCREEN
1000     17958  0.5  0.0   5172  2356 pts/3    Ss+  02:58   0:00              \_ /bin/bash

[warezwaldo@m0b1l3 ~]$ ps auxf|grep "screen"|awk '{print $2}'
17969 <-- this is the search for screen in the above one liner
17956
The top number in this search will be your search string itself, the second will be the actual process.

To answer your question in regards to 1 pid being lower than the pid started before it, and yes this can happen, it usually doesn't happen until you have used all of the systems process id count limit and it resets. The answer to your second question in regards to killing a process that had output piped to it, and the answer is Yes this is a bad thing. You are creating what are called Zombie processes when you do this as the Java app is going to continue to run but it really isn't doing anything as it no longer has a means of output as you originally redirected its output to tee. This causes system resources to be allocated but not used. If enough of these processes stack up and are not killed off you will eventually cause your machine to crash. What you are actually doing is creating a "Memory" leak and not a small one, as Java by nature requires lots of resources to run.

You would be better off killing the Java process that you start with that script as it is really what you want to stop. By killing the Java process you will kill the tee process and any other process that you piped the results of the java program to. So if you did something like this:
Code:
#!/bin/bash
#killer
command=$1

for i in `ps auxf|grep "$command"|awk '{print $2}'`
do
        echo "PID: $i"
        kill -9 $i
done


[warezwaldo@m0b1l3 ~]$ ./killer vim
PID: 20591
PID: 20601
Killed
That should accomplish what you are looking to do. This script would require feeding the command that you are looking for. So you could just duplicate for each of the commands or if you are keeping track of the process IDs as they are started you could just past that to the kill command: kill -9 PID

To be honest I cannot remember what $! actually pulls but the above method might be an easier way to accomplish the task.

using the following will KILL the process -- kill -9 PID

Last edited by War3zWad|0; 12-24-2011 at 05:06 AM. Reason: forgot usage
 
1 members found this post helpful.
Old 12-24-2011, 07:53 AM   #3
wahoodoss
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
Thanks for the response War3zWad. I will check this out when I get back to work on Tuesday.

Bill
 
Old 12-24-2011, 01:56 PM   #4
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
Here's another approach for you to consider. It uses pstree, grep, and sed.
Code:
pstree -lp <parentID> | grep -o '([0-9]\+)' | sed 's@[()]@@g'
That command will give you a list of all the descendant process IDs of the given <parentID>.

For instance, on my system right now:
Code:
$ pstree -p
<snip>
        ├─gdm3(1441)─┬─gdm-simple-slav(1449)─┬─Xorg(1452)
        │            │                       ├─gdm-session-wor(2052)─┬─x-session-manag(2391)─┬─bluetooth-apple(2479)
        │            │                       │                       │                       ├─gdu-notificatio(2488)
        │            │                       │                       │                       ├─gkrellm(2477)
        │            │                       │                       │                       ├─gnome-panel(2459)
        │            │                       │                       │                       ├─gnome-power-man(2455)
        │            │                       │                       │                       ├─kerneloops-appl(2487)
        │            │                       │                       │                       ├─metacity(2457)
        │            │                       │                       │                       ├─nautilus(24935)───{nautilus}(24937)
        │            │                       │                       │                       ├─nm-applet(2496)
        │            │                       │                       │                       ├─polkit-gnome-au(2490)───{polkit-gnome-a}(3682)
        │            │                       │                       │                       ├─python(2478)─┬─bash(2517)───man(4787)───pager(4798)
        │            │                       │                       │                       │              ├─bash(2609)───ssh(13370)
        │            │                       │                       │                       │              ├─bash(7193)───gnuplot(30805)───{gnuplot}(30815)
        │            │                       │                       │                       │              ├─bash(29983)───pstree(16740)
        │            │                       │                       │                       │              └─{python}(2518)
        │            │                       │                       │                       ├─seahorse-agent(2439)
        │            │                       │                       │                       ├─ssh-agent(2425)
        │            │                       │                       │                       ├─update-notifier(2489)
        │            │                       │                       │                       └─{x-session-mana}(2448)
        │            │                       │                       └─{gdm-session-wo}(2392)
        │            │                       └─{gdm-simple-sla}(1453)
        │            └─{gdm3}(1450)
<snip>
$ pstree -lp 1441 | grep -o '([0-9]\+)' | sed 's@[()]@@g'
1441
1449
1452
2052
2391
2479
2488
2477
2459
2455
2487
2457
24935
24937
2496
2490
3682
2478
2517
4787
4798
2609
13370
7193
30805
30815
29983
16664
16663
16665
2518
2439
2425
2489
2448
2392
1453
1450
If your Java app is responsible for spawning all your sub-processes, then its process ID is what you'd want to use of course. Also, keep in mind that the parent process ID given on the command line appears in the output. So, you'll need to check for that before sending out your kill command(s)
 
1 members found this post helpful.
Old 12-27-2011, 10:04 AM   #5
wahoodoss
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
Hey guys ... Thanks for the responses. They were very helpful.

I consider this problem solved!!

Bill
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] What is the exact process involved in creating installable .iso "snapshots" .. exoshwarze Linux - Distributions 5 07-16-2011 12:59 PM
echo "hahaha" | sudo tee /root/reallyimportantstuff crispyleif Linux - Security 7 01-24-2009 11:51 AM
"cheese" capturing working a lot better under Ubuntu than Fedora ed_homeLinux Linux - Software 2 10-14-2008 07:32 PM
Standard commands give "-bash: open: command not found" even in "su -" and "su root" mibo12 Linux - General 4 11-11-2007 10:18 PM
SSH "Connection Refused" problem when there is no firewall/router involved in Fedora4 d2army Linux - Networking 5 10-04-2005 05:01 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 10:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration