User tasks in ~/.logout
Karl Vogel
vogelke+unix at pobox.com
Wed Oct 12 03:36:42 UTC 2011
>> On Tue, 11 Oct 2011, Polytropon wrote:
P> I have some users who I want to "schedule" a specific job for which gets
P> executed on their user account. For some of them, it will be twice a
P> day, for others just once a month. It should happen at logout time.
If using the ~/.logout file works, fine, but...
P> The only thing is to educate users to...
...may the deity of your choice help you. How about this?
1. Run the "onlogout" program below once a minute from cron. You can
run it as root, since it uses "last" to figure out who's logged out
recently, and "su" to run something as that user. I opened a new xterm,
connected via ssh to a BSD box, and closed the window without logging
out; "last" showed my session properly, so your users probably won't
need to change the way they do things.
2. "onlogout" runs another script called "runone", which uses "lockf"
to make sure that only one instance is running for a given user at
a time. The example below just prints the date and sleeps for a
few seconds to demonstrate the locking, but you could personalize
it by running "~/.disconnect" if it exists; "su -l" should set the
environment properly.
"onlogout" keeps the previous most recent 20 lines from "last" to see
what's changed since the previous run. If your system is really active,
you'll have to tweak that.
Over-engineered? Probably, but the combination of no user education plus
safely running *one* copy of a backup job (or whatever) on user logout
might be worth it.
--
Karl Vogel I don't speak for the USAF or my company
Handy engineering conversions: 1000 aches = 1 kilohurtz
---------------------------------------------------------------------------
#!/bin/ksh
#<onlogout: run something when someone disconnects.
export PATH=/usr/local/bin:/bin:/usr/bin
work=/var/disconnect
# Find who's logged out recently.
test -d $work || mkdir $work || exit 1
cd $work
last -n 20 > new
if test -f old
then
list=$(diff old new | grep -v 'still logged in' |
grep '^>' | awk '{print $2}' | sort -u)
else
mv new old
exit 0
fi
# Start a specific job for each one.
for name in $list
do
su -l $name -c '/usr/sbin/daemon /path/to/runone'
done
mv new old
exit 0
---------------------------------------------------------------------------
#!/bin/ksh
#<runone: run one instance of a program.
export PATH=/usr/local/bin:/bin:/usr/bin
umask 022
tag=${0##*/}
# Execute this while holding the lock file, to ensure that multiple
# instances won't collide with one another. You'll get the message
# lockf: /var/spool/lock/runone.username: already locked
# if you try to start a second instance while one is running.
lock=/var/spool/lock/${tag}.${USER} # Pick a good lock directory
(
lockf -t 0 ${lock} /bin/sh << EndProgram
date "+update PID $$ starts at %Y/%m/%d %H:%M:%S"
sleep 10
EndProgram
) &
exit 0
More information about the freebsd-questions
mailing list