Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
I've got a BASH script which runs when a user logs in. When a user logs out the script keeps on running. Which is Bad. I'm wondering if anyone can explain how to make the script die when a user logs out.
I've considered making the script check if the user is still logged in by looking at the output of 'who' but had to scrap that when I discovered that a user logged in via an NX session doesn't show up in the output of 'who'. (Whole other issue.) Also that would just be a workaround to the problem rather than a solution.
#!/bin/bash
while true; do
sleep 600
date > /dev/null
done
I wonder if the problem is related to the use of the while true loop though the script exits fine if I use 'kill PID' from the command line.
N.B. this is not actually the script I'm having trouble with as that's rather long, it's a nice short script which does essentially the same thing (sleep for a while and then do something, all wrapped in a while true loop) that demonstrates the problem I'm having.
Unfortunately putting it in ~/.config or ~/anything is no good. I have thousands of users who could log in to the machines. Modifying all their home directories would be madness. (Also for technical reasons I can't actually do that myself.) I need to start the script from a system wide directory. I tried using /etc/xdg/autostart but that makes no difference.
I've tried trapping various combinations of TERM INT and EXIT like so:
Code:
#!/bin/bash
trap "{ touch /tmp/blah; exit 0; }" TERM INT EXIT
while true; do
sleep 600
date > /dev/null
done
It doesn't make any difference.
I know the trap syntax is good because if I include INT, run the script from a command prompt then press ctrl-c the time stamp on /tmp/blah gets changed.
I've come up against a similar problem before. What I think might be happening is that the sleep subprocces is not being killed. As suggested by another poster I tried to implement a trap to kill it, but couldn't get it to work. What might work for you is to replace the loop with a recursive call of the script. In this case your example would become:
Hm,
stupid me. My recursive script won't work. Please try the following trap. I should kill the whole process group (ie including the sleep) when the parent script is killed. The key here is the minus sign in front of the pid. The -- is needed so that kill does not interpret it a switch.
Code:
#!/bin/bash
trap "/bin/kill -- -$$" EXIT
while true; do
sleep 600
date > /dev/null
done
I tried 'trap "/bin/kill -- -$$" EXIT'. No effect. I also tried adding TERM INT and HUP to the list of things to catch just for the hell of it.
Then I tried a slightly different method of doing the same thing:
Code:
#!/bin/bash
trap "touch /tmp/blah ; pkill -P $$; exit 0" EXIT TERM INT HUP
while true;do
sleep 600
date > /dev/null
done
That doesn't work either. Also /tmp/blah doesn't get touched. It does get touched if I manual kill the process after log out using 'kill PID'. This leads me to wonder if maybe the problem is that when the GNOME session ends the script just isn't being sent any of EXIT TERM INT HUP. Though why that should be or what it could be being sent instead I have no idea.
Right now I am using the GDM PostSesssion script to clean up the problem script after a user logs out. However if a user logs in with NX then GDM isn't used, so the script keeps running when user logs out. I can do something with NX to clean the script up as I've done for GDM, but that's just adding in another work around. Rather than keep adding workarounds, I'd really like to solve the problem of why the script doesn't get killed when the GNOME session ends. All the other children of the gnome-session process get killed, yet my script doesn't.
I think I've come up with an acceptable solution. It's a workaround, which is irritating, but it's a workaround contained in the script itself rather than one that relies upon another script, such as a GDM session script.
Code:
#!/bin/bash
parentpid=$PPID
while true;do
sleep 600
date > /dev/null
# check if original parent process is still running.
# if not, exit.
if [ ! -d /proc/$parentpid ];then
exit 0;
fi
done
The script still does not get killed when the user logs out as, IMO, it really should be, however it does exit of it's own accord within 600 seconds (or whatever value is given to sleep) of the user logging out.
Last edited by arizonagroovejet; 11-06-2009 at 02:33 AM.
Reason: -d not -f - thanks to kdp
Doh. Yeah of course they're directories, not files. I did actually know that despite the evidence to the contrary Thanks for pointing it out. With -f the script would die after 600 seconds even if the original parent process was still running. In testing I was logging in then out again within the 600 seconds and hence my error didn't show up. I've edited the script in my previous post to avoid someone else possibly copy/pasting a non-working version.
I'm sure the script will work properly with the -d but I'll test it later on when I have time just to make sure
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.