How to kill a tree of processes?

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
Wognath
Posts: 423
Joined: Sun 19 Apr 2009, 17:23

How to kill a tree of processes?

#1 Post by Wognath »

Hello,
I have a script that generates a bunch of background and child processes.

Code: Select all

# pstree -p 30130
script(30130)─┬─sit(30131)───{gmain}(30149)
                    ├─script(30146)───yad(30150)
                    ├─script(30164)───yad(30167)
                    └─sleep(30214)
I would like to find an efficient mechanism to kill everything in the tree when the script closes.
Maybe the simplest is to start the script via terminal (rxvt -e script) and kill the terminal to exit. But what if I don't want a terminal hanging around?
After a lot of googling, I haven't found much else, since most suggestions, such as ps --ppid 30130 miss the background processes. This works, but it sure is awkward:

Code: Select all

# x=`pstree -p $$`          
n=2 ; k="start" ; list="kill"
while [[ -n $k ]] ; do k=`echo $x | cut -d\( -f$n | cut -d\) -f1` ; list=$list" $k" ; let n++ ; done 
$list
( $x="script(30130)-+-sit(30131)..." and $list="kill 30130 30131...")
There must be a neater way to do this. Or at least a way to print out a list from pstree. I'll appreciate your information. Thanks

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#2 Post by MochiMoppel »

Wouldn't pkill do the job when you add it to your parent script?

Code: Select all

#!/bin/bash
trap "pkill -P $$" EXIT
xmessage "First child" &
xmessage "Second child" &
xmessage "Closing this should also close First and Second child" 

Wognath
Posts: 423
Joined: Sun 19 Apr 2009, 17:23

#3 Post by Wognath »

Thanks for that, MochiMoppel. My script is a reminder that runs an endless loop, with this structure:

Code: Select all

sit icon.jpg "tooltip" "L-click action" "R-click action" & 
	
while true ; do
	for i in first second third ; do Xdialog --yesno $i 0 0 & done
	sleep 3600
done
So I had no success with trap...EXIT, but using pkill -P helps.
If "{ pkill -P $$ ; kill $$ ; }" is used as L-click action in sit, it almost works: kills open Xdialogs, sit and the script, but the Xdialogs are immediately repeated and left open. I guess sleep is killed and the for loop runs once more before $$ is killed. Adding sleep 0.1 before "for i..." fixes that.
"pkill -P $$" makes sit disappear but the loop continues running.
With "kill $$", sit keeps running, but the loop stops.

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#4 Post by musher0 »

Hello Wognath.

Here is an article about various "kill" command in Linux, that may clarify things a little.

BFN.

PS: Have you tried killing the calling script itself and not the individual
commands in it?

Let's say your entire script is called smurf.sh. You start your smurf.sh script.
At some point, you want to stop it. What happens if you type in console

Code: Select all

killall -q smurf.sh
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

TeX Dog
Posts: 287
Joined: Wed 06 Jul 2016, 17:57

#5 Post by TeX Dog »

ps also has a tree command switch, maybe easier

Wognath
Posts: 423
Joined: Sun 19 Apr 2009, 17:23

#6 Post by Wognath »

There are so many kill and process commands, I'm surprised there is no single command to "stop this script and anything it started". But the command pkill -P suggested by MochiMoppel does the job. Thanks! .. EDIT: kills child processes as I needed, but a child of child would not be killed

Code: Select all

pkill -P $$ ; exit        (or pkill -P $$ ; kill $$ )
Musher: Thanks. killall does not appear to kill child processes nor have an option to do so.

Code: Select all

# pstree -p 23787
test(23787)─┬─Xdialog(23789)
            ├─Xdialog(23790)
            ├─Xdialog(23791)
            ├─sit(23788)───{gmain}(23793)
            └─sleep(23792)
# killall -q test
# pgrep Xdialog
23789
23790
23791
Tex Dog, Thanks, but I can’t get anywhere with ps -H :(
Last edited by Wognath on Thu 01 Dec 2016, 19:25, edited 1 time in total.

TeX Dog
Posts: 287
Joined: Wed 06 Jul 2016, 17:57

#7 Post by TeX Dog »

Code: Select all

ps -f -h
part of the format command

Wognath
Posts: 423
Joined: Sun 19 Apr 2009, 17:23

#8 Post by Wognath »

Always interested to know what I've missed and if there's a neater way to do this. I just want to add to the topic this recursive function from https://stackoverflow.com/questions/177 ... nt-process, another way to get all pid's in a tree:

Code: Select all

function getcpid() {   
    cpids=`pgrep -P $1|xargs`
    for cpid in $cpids; do
        a=$a" "$cpid
        getcpid $cpid
    done
}

pstree -p 5510
first(5510)─┬─second(5512)─┬─third(5515)───xmessage(5516)
                │                       └─xmessage(5514)
                └─xmessage(5511)

a="" ; getcpid 5510 ; echo $a
5511 5512 5514 5515 5516
ps -f -h -> same information along with a lot of clutter; I haven't figured it out yet :?
pgrep -P 5510 gives only 5511 and 5512
If there were a way to get pstree to print a list, the function would be unnecessary.

jamesbond
Posts: 3433
Joined: Mon 26 Feb 2007, 05:02
Location: The Blue Marble

#9 Post by jamesbond »

Check process tree in case you don't have pstree

Code: Select all

ps -e -o pid,ppid,pgrp,sess,comm f
Or, you could get the same with "pstree -p -g".

Run process in a group and kill them all when the parent dies, without the need for getting the list of PIDs and kill them one by one:

Code: Select all

#!/bin/ash

[ -z "$1" ] && exec setsid $0 ok  # THE MAGIC

echo $$
do_work() {
	local count
	touch /tmp/zzz.svg
	sit /tmp/zzz.svg &
	count=0
	while true; do
		cat > /tmp/zzz.svg << EOF
<svg width="24" height="24">
<text x="6" y="12" font-size="12px" fill="white">$count</text>
</svg>
EOF
		: $((count=count+1))
		sleep 1
	done
}

do_work &
Xdialog --msgbox "Click OK when done." 0 0
/bin/kill -- "-$$" # THE MAGIC
Pay attention to the "THE MAGIC" - that what is needed to make it works.
If you use bash (#!/bin/sh instead of #!/bin/ash at the top), you can just use "kill" instead of /bin/kill.
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]

Wognath
Posts: 423
Joined: Sun 19 Apr 2009, 17:23

#10 Post by Wognath »

Awesome! Thanks, James. ;) I understood your script immediately! :lol:
Attachments
icon.png
MANY hours later... (not off topic: sit R-click option is THE MAGIC :)
(10.41 KiB) Downloaded 196 times
Last edited by Wognath on Sat 03 Dec 2016, 20:34, edited 1 time in total.

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#11 Post by musher0 »

Hello all.

Not an answer to the exact question being asked, but in the same line
of thought:

The following script gets some info, displays it for 7 seconds and then
commits suicide with a sense of responsibility, meaning: it kills only itself.

Code: Select all

#!/bin/sh
# /root/.pekwm/current-theme.sh # Dép. : awk
####
[ "${LANG:0:2}" = "fr" ] && TITR="Thème actuel de pekwm" || TITR="Current pekwm theme"
awk -F"/" '$1 ~ /Theme/ { print "\""$NF }' /root/.pekwm/config > /tmp/pekwm-theme
urxvt -T "$TITR" +sb -fn "xft:Monaco:pixelsize=14:antialias=true:autohint=true" -g 28x2-70+70 -e less -~ -P "$TITR" /tmp/pekwm-theme &
sleep 7s
kill -s 15 `ps | awk '$0 ~ /actuel|Current/ && $4=="less" { print $1 }'`
Using awk on the last line of the script allows you to search the ps results
on 2 fields. This makes the killing very precise: you could have 10 less
scripts running, but only the one you intend to kill gets killed.

BFN
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

Wognath
Posts: 423
Joined: Sun 19 Apr 2009, 17:23

#12 Post by Wognath »

Hi Musher,
I learned a lot from studying your script (likewise jamesbond's). I created a dummy /tmp/pekwm-theme file and proceeded to have hours of fun :? I think it is relevant to the topic since "less" is a grandchild of "musher" (as I renamed your script).

Code: Select all

pstree -pa 20280
musher,20280 /tmp/musher
  └─urxvt,20282 -T Current pekwm theme +sb -fn...
      └─less,20284 -~ -P Current pekwm theme /tmp/pekwm-theme
In this case, since killing urxvt kills processes running in it, pkill -P $$ would also work. Of course it's not as specific.

We must use different defaults, since I found that on my system I have to use ps -ef; otherwise "Current" does not appear in any field. With ps -f, field $1 -> $2 and $4 -> $8

Code: Select all

# ps -ef | awk '$0 ~ /actuel|Current/ && $8=="less" { print $2 }'
20284
Thanks, Musher and James, for the educational examples.

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#13 Post by musher0 »

Hello Wognath.

I'm glad my script was of some use to you.

Attached is the pekwm config file used in my script example. Sorry for
any inconvenience, I didn't think of uploading it earlier / above, that you
would try to reproduce the experiment! :)

I agree that killing urxvt will do the job. Depends on what your need is,
of course.

As for me, over time, I evolved kind of a system using the full less (not
the busybox one) as a substitute for Xmessage. So I may have at times
3-4 less's running, a couple for reading docs, one to display a calendar,
another one for a message (such as in the case above).

Now with the way I do it, less is always supported / launched by urxvt. I
felt I needed a way to kill only one process at a time (contrary to your
approach). It would have been frustrating / impractical for me to kill all
urxvt's and interrupt my reading of an important doc with less, for ex.,
running as another process.

Again, it depends on your need. Sometimes killing all urxvt processes
is the exact thing to do.

BFN.
Attachments
pekwmConfigFile.zip
For testing the script in previous post. Unzip in /root/.pekwm
(1.2 KiB) Downloaded 94 times
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#14 Post by musher0 »

@Wognath:

It just occurred to me: which "less" are you using, the real one or the
busybox one?

If you are using the busybox less, it's a terribly trimmed down version.
Its help has four lines, whereas the help for the real less has four pages!

Type < busybox less --help > and < less --help > in succession. If you
get the same thing, you do NOT have the real less installed.

The -P parameter for less in my script exists only in the real less; it
wouldn't be recognized by the busybox less. So the string that follows the
-P won't show with < ps | grep less > or < ps | awk '$4 ~ /less/' >.

Speaking of the real less, a new version is out. Here you'll find a pet for it.

BFN.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

Wognath
Posts: 423
Joined: Sun 19 Apr 2009, 17:23

#15 Post by Wognath »

Hi Musher,
The de luxe version of less, with the imposing help file, comes with Fatdog. It has been on my agenda to learn more about its use. What a great thread this turned out to be! I learned about process groups and trees, svg, awk and less :)

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#16 Post by musher0 »

Wognath wrote:Hi Musher,
The de luxe version of less, with the imposing help file, comes with Fatdog. It has been on my agenda to learn more about its use. What a great thread this turned out to be! I learned about process groups and trees, svg, awk and less :)
Hi Wognath.

I'm happy that this thread is a plus for you. However...

I hate to be telling anyone what to think, but:
-- historically the less by greenwood software came first. It was invented in 1983.
Where did less come from?

Back in 1983, I was working for a now-defunct company called Integrated Office Systems. Some of our software ran on a Unix system and produced enormous log files of its transactions. We wanted to be able to search these log files for error messages. But the version of "vi" we were using couldn't handle files larger than a certain size, and our log files often exceeded that size. So we were forced to use "more" to view the files. The problem was, once we found an error message, what we really wanted to see was the transactions leading up to the error; that is, the lines in the log file immediately before the error message. But more didn't allow backward movement in the file.

We often complained about this problem. We said we needed a "backwards more"; someone (it wasn't me, but unfortunately I don't remember who it was) coined the name "less" as a joke on the concept of a "backwards more". It didn't seem to me that it would be too difficult to write a simple pager that would allow forward and backward movement. I wrote the first version in late 1983 and we began using it internally. I continued to enhance it and finally decided it was a useful enough tool that I should make it available to the world. I posted the first version to the newsgroup called (at that time) net.sources in May, 1985.

Making the program publicly available allowed an enormous number of people to use it. Many people have made their own modifications and donated them to me for incorporation into the official version, and many more have reported bugs they've found or made suggestions about features they'd like to see added. This was my first experience with the concept of what is now called "open source" or "free software", and it has, I believe, produced a very high quality product. I'd like to thank all the users of less for their invaluable comments and suggestions over the years. Less wouldn't be what it is today without you.
Source:http://www.greenwoodsoftware.com/less/faq.html#history

It is therefore the real less. It is NOT a "deluxe" version of the busybox
version. It's the other way around: the busybox people took an excellent
utility that already existed and made a mockery of it.

Unfortunately, they do that a lot. Another example is their lsof, and so on,
and so forth. They've redeemed themselves by a hair by including a good
ash implementation in their package, and that's about it.

I'm just half-sorry for getting emotional here, because sometimes getting
emotional about something is useful to set things straight. As in this case.

Best regards.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

TeX Dog
Posts: 287
Joined: Wed 06 Jul 2016, 17:57

#17 Post by TeX Dog »

My word, that story of less sounds so like I was there, I got hired to cut and solder ends for networking at a company in 1983 called Interactive Business Systems as a Senior in high school. The guy who also worked there had to leave for military, got them to keep me on as a coder, The Boss PeteK gave me 100 dollars and told me to get some books on C, the only other person in company that knew C well was Mark and he gave wrote me a list of C book to get if the bookstore had them. Spent most of the 100, which I was not suppose to spend it all.

TeX Dog
Posts: 287
Joined: Wed 06 Jul 2016, 17:57

#18 Post by TeX Dog »

I stay with I.B.S. till I finished my Electronic Degree and was the last employee :cry: I got accepted to another college for another degree on scholarship and the weekend before I left town help move the office chairs/ remains into storage.. There where actual tears.
Mark wisely left for greener pastures, but was 'on-call' to answer Qs so saw him often, usually semi-socially since he did not want to be conned into working directly with IBS again.

User avatar
drunkjedi
Posts: 882
Joined: Mon 25 May 2015, 02:50

#19 Post by drunkjedi »

Hey musher, just a curiosity...
If puppy was built without busybox, what would be the size increase in puppy?

TeX Dog
Posts: 287
Joined: Wed 06 Jul 2016, 17:57

#20 Post by TeX Dog »

Having no idea our more <heavily modified version later to become less> was unique I recall using real more and complaining it was missing stuff on other platform/ outside of work :roll:
1985 sounds right I was with a group and we where discussing the mods and renaming. It was NOT at a place that had food, was my biggest memory, did not hit my adult growth til 86 always hungry.

Post Reply