LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-21-2009, 09:54 PM   #1
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Question bash `kill`: process 'B' silently dies; but process 'A' = `kill` spews back debris!


Yesss....

I'm dealing with a couple weird little 'bash-isms' here this evening.

Here's the situation (the first one anyway):

Process 'A' is a forked off TAIL command, simply following a logfile and dumping the tailed output to another file.
When I fork it from the bash script, I grap the PID from '$!' and save it to a pidfile.

Process 'B' is a forked off function in this bash script, which again, after forking it I grab the PID and save it to a pidfile; like so (very simplified):

Code:
#!/bin/bash

silly_function_name () {
sleep 10000
blah blah
}

case $1 in
 start)
  tail -f /some/log > some/file &
   echo $! > pidfile_A
   silly_function_name &
    echo $! > pidfile_B
    ;;
 stop)
    kill `cat pidfile_A`
    kill `cat pidfile_B`
    ;;
esac;

exit 0
OK, so I run the script, which has a START and STOP argument I can send to it, like so:

sh# ./script start

..so far so good.

sh# ./script stop

..now, the crap: function fork dies silently with no feedback from `kill`; but killing the TAIL command fork returns the likes of:

Code:
[1] 35242  Terminated             tail -f /some/file  >some/other/file
to the console. I don't want that.

Now, I should mention that this effect does NOT happen if I start a tail fork from the command-line, and then kill it with `kill 1234` ; it dies silently with no feedback. But when I run the script, voila! ugly feedback from kill, but ONLY from killing the tail command, not from killing the function that was forked.

Also, I've tried directing STDERR and STDOUT to /dev/null or to a file, and I've tried trapping the feedback in a $variable, and I've tried piping it into other stuff, but nothing supresses the 'Terminated' message.

Anyone have any insight?

Heres situation 2:

Assuming the same script as above; the function in the script contains a 'sleep' command. When I start the script, and the function forks, I can look at `ps ax` and I can see the function's process itself, and I can also see that a sleep thread has been created by it. That's all fine and dandy, however when I stop the script, or kill the function with `kill 1234` the sleep thread remains in the ps list. It isn't zombified, it's 'sleeping'.
Why is it still there??
Since it was within the function, I like to think that killing the function itself, would terminate the sleep thread as well.

Why not??



Sasha

Last edited by GrapefruiTgirl; 06-22-2009 at 07:48 PM. Reason: changed function name for clarity
 
Old 06-22-2009, 08:22 AM   #2
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
I have come up with a solution, or a work-around, for situation one.

by changing the `kill` statement to:

Code:
pid=`cat $pidfile`
kill $pid > /dev/null 2>&1 &
wait
the 'Terminated..' line is eliminated. Not sure if I need to background the kill statement (but in the real-life context in which it's being used, it works); the main issue was *probably/possibly* that I was doing the shell redirection improperly.

Situation TWO from my first post still astounds and amazes and I haven't figured out why the `sleep` thread doesn't terminate when its parent process dies.

Sasha
 
Old 06-22-2009, 03:48 PM   #3
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
plus, function is a keyword.

Code:
Functions are declared using this syntax:

     [ function ] name () compound-command [ redirections ]
 
Old 06-22-2009, 07:50 PM   #4
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Thanks for the heads-up re: 'function'

Quote:
Originally Posted by bigearsbilly View Post
plus, function is a keyword.

Code:
Functions are declared using this syntax:

     [ function ] name () compound-command [ redirections ]
Thanks Billy, I hadn't even thought of that.

In the real-world program I am working on, the function is not actually named 'function' -- that was a poor choice of function names in my example, and I have corrected it.

So, the sleep thread problem still exists as it did.

Sasha
 
Old 06-22-2009, 09:15 PM   #5
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 792

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
I piddled (no pun intended) with this a little today and my sid system doesn't issue the warning when I run the stop option. I understand that your script is more complex than the description that you gave but it seems odd that Slackware and Debian would behave differently. Maybe it's a bash shell option like "notify" that is set differently. Dunno.

Here's the code that I ran (pretty much exactly like your example):
Code:
!/bin/bash

bar () { sleep 300; }

case $1 in
 start)
    tail -f /var/log/syslog > tail_output &
    echo $! > pidfile_A
    bar & 
    echo $! > pidfile_B
    ;;
 stop)
    kill `cat pidfile_A`
    kill `cat pidfile_B`
    ;;
esac;
exit 0
Code:
./foo.sh start
ps -aux
user  10151  0.0  0.1   3100   552 pts/1    S    20:44   0:00 tail -f /var/log/syslog
user  10152  0.0  0.1   4864   960 pts/1    S    20:44   0:00 /bin/bash
user  10153  0.0  0.0   3076   504 pts/1    S    20:44   0:00 sleep 300
Code:
cat pidf*
10151
10152
Code:
./foo.sh stop
ps -aux
user  10089  0.0  0.4   4864  2072 pts/1    Rs   20:41   0:00 /bin/bash
user  10153  0.0  0.0   3076   508 pts/1    S    20:56   0:00 sleep 300
As I said, if stop is run there is no output. It kills two processes and leaves the sleep process running. My guess is that it has to spawn a shell in order to put the function in the background and that is what is captured with "$!". I don't think a normal function call is a process.

Really no solution offered above but I thought that I would share my experiences with you.

Finally to the point of my post: I did find some interesting discussion about killing parent and child processes right here on LQ (where else?) but I haven't tried any of the suggestions: link link
 
Old 06-22-2009, 09:29 PM   #6
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
@ norobro,

Thanks for taking the time to do some experimenting on the subject. It is most interesting: as we see, the same thing happens on your system regarding the sleep command/thread.. It stays alive until it times out. Weird. I could kill it, but sheesh, it's looking like I'm creating quite a pile of pidfiles to deal with, for one rather small script

As you speculated, possibly different versions of BASH are in play, or different BASH configurations on different systems. FWIW my current BASH is version 3.1.17(2), not the one that came with my Slack OS.

The outputs from the script when I stop/kill it are not really detrimental or serious, but I am super-detail-oriented, perhaps too much so sometimes (obsessive with detail ? ?) heh heh. Maybe I'm too picky; but something I find annoying is when a script has executed completely and returns the prompt to the user, then suddenly some more output spews forth from the remaining backgrounded process. I don't like it.

Well, it has been a long and tiresome day for me; I will have to look at those two threads you linked to above, but it will be tomorrow. I'm about thru for today.

Thanks again for the input and testing!

Sasha
 
Old 06-23-2009, 05:08 AM   #7
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
well, on the command line
bash and ksh
both produce terminated whether backgrounded as
a function or as a straight command.

I tried the script (apart from changing it to #!/bin/bash
and /var/log/messages -- I get no terminated messages.

when you call a function it spawns a new shell this is the number
returned in $!. sleep also spawns a new process. so you are killing the
shell not the sleep.

an interactive shell passes signals on to it's children, this would imply that a non-interactive
shell does not. I would assume a function to be a non interactive shell.

even though, if you do a sleep & and exit the shell it still doesn't die (the sleep)

the plit thockens
 
Old 06-23-2009, 09:26 AM   #8
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 792

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
Quote:
Originally Posted by bigearsbilly View Post
I tried the script (apart from changing it to #!/bin/bash
This typo is a pretty easily caught. Think I should edit my post?
Quote:
Originally Posted by bigearsbilly View Post
well, on the command line
bash and ksh
both produce terminated whether backgrounded as
a function or as a straight command.
Looking back, I misread or misunderstood GrapefruiTgirl's op. I thought that she was getting the terminated message from her script.

If you don't background the function and instead "bg" the sleep, GrapefruiTgirl's script works like a charm. So it seems that in order to "bg" something that doesn't normally require a separate process, bash has to spawn a shell. Thus creating the issue of being able to kill the parent process and all child processes.
 
Old 06-23-2009, 09:39 AM   #9
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Exclamation ..something so simple.. er... not!

Quote:
Originally Posted by bigearsbilly View Post
well, on the command line
bash and ksh
both produce terminated whether backgrounded as
a function or as a straight command.
.. and it's HARD to shut up the 'Terminated' message.. /dev/null doesn't seem to absorb it.

Quote:

I tried the script (apart from changing it to #!/bin/bash
and /var/log/messages -- I get no terminated messages.
I get the impression you are subtly telling me something in the above, re: changing the shell statement to #!/bin/bash .. so?

Quote:
when you call a function it spawns a new shell this is the number
returned in $!. sleep also spawns a new process. so you are killing the
shell not the sleep.
Right.

Quote:

an interactive shell passes signals on to it's children; this [what we're learning here] would imply that a non-interactive
shell does not. I would assume a function to be a non interactive shell.
Sounds good to me, and seems correct.
Quote:

even though, if you do a sleep & and exit the shell it still doesn't die (the sleep)
Correct, the sleep does not die. It sleeps until it awakes, at which point it vaporizes. That's exactly what's pesky about this sleep thing.

Here's some console output to ponder (just executed in the console-- no deliberately spawned shells or scripts, and ignore the orange for a moment.). It's early here for me, so I'm not fully 'online' yet. :

Code:
sh-3.1# sleep 1000 &
[1] 23664
sh-3.1# kill 23664
sh-3.1#
[1]+  Terminated              sleep 1000

sh-3.1# sleep 1000 &
[1] 23704
sh-3.1# kill 23704 > /dev/null 2>&1
sh-3.1#
[1]+  Terminated              sleep 1000

sh-3.1# sleep 1000 &
[1] 23891
sh-3.1# kill 23891 > /dev/null 2>&1 &
[2] 23940
[1]-  Terminated              sleep 1000
[2]+  Done                    kill 23891 >/dev/null 2>&1

sh-3.1# sleep 1000 &
[1] 23971
sh-3.1# kill 23971 & > /dev/null 2>&1
[2] 24033
[1]-  Terminated              sleep 1000
[2]+  Done                    kill 23971
sh-3.1#
Notes/observations:
1) The line I bolded does not appear until I hit another keystroke (like pres RETURN at the prompt).
2) The 'Terminated' report is returned no matter what I do to try to hide it.

3) If I do the above examples from within a SCRIPT, the 'Terminated' report can be hidden, BUT:
3a) doing that like:
Code:
kill `cat $pidfile`
or 
kill `cat $pidfile` &
wait
both spew back the Terminated line every time.. However, here's some in-script examples for comparison:
Code:
in-script examples 1 (returns 'Terminated' line no matter where/how I redirect output)
kill `cat $pidfile` > /dev/null 2>&1
kill `cat $pidfile` > /dev/null 2>&1 &

in-script example 2 (same result)
var=`cat $pidfile`
kill $var > /dev/null 2>&1

in-script example 3 (same result)
var=`cat $pidfile`
kill $var > /dev/null 2>&1 &

in-script example 4 (same result)
var=`cat $pidfile`
kill $var > /dev/null 2>&1 &

in-script example 5 (THIS HIDES the 'Terminated' line,
BUT ONLY if the wait command is after it, presumably
because the 'Terminated' message is delivered to the imaginary console
created by forking the KILL command, and the WAIT command
keeps output confined to that imaginary console, returning only
AFTER the 'Terminated' message has been displayed in that imaginary console;
This is the same as the orange example earlier.)
var=`cat $pidfile`
kill $var > /dev/null 2>&1 &
wait
In my real-life script, here's what it looks like (and it works great, despite being round-a-bout IMO).
note that elsewhere in the script, some_function () was forked, and $! was saved as $function_pid
Code:
sleep_pid=`ps ax | grep $(pgrep -P $function_pid) | gawk '{/^.[:digit:]+[ ]$/;print $1}'`
kill $function_pid > /dev/null 2>&1 &
wait;
kill $sleep_pid > /dev/null 2>&1 &
wait;
it works perfect.

I dunno if me or anyone can make much sense out of this post as a whole; as I said, it's early; I'm still on the first coffee.

Sasha

PS - I don't know how/why this thread is in the 'NON *NIX' programming forum.. Seems *NIXy enough to me..
 
Old 06-23-2009, 09:42 AM   #10
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Oh -- and @ norobro,

Those links you gave at the bottom of youe earlier post DID lead me to the working solution I have now in my actual real script. Some of the examples did NOT work for me as they did for the user(s) in those posts, but I managed to adjust what I read there and get a working result.

Link #2 was the more helpful to me. Thank you again.

Sasha
 
  


Reply

Tags
bash, kill, process



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
How to get the PID of the process giving kill signal to a process? hariprd Programming 2 11-27-2008 03:10 AM
Shell Script : Kill a running process when another process starts ashmew2 Linux - General 3 08-20-2008 03:47 AM
cannot kill process (kill -9 does not work) mazer13a Linux - General 1 05-27-2005 02:32 PM
how do i kill a process from inside a bash script? mikaelo Programming 4 05-28-2004 08:51 AM
BASH script inform user and kill process mounters Programming 3 02-11-2002 04:57 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:58 PM.

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