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