/bin/sh Madness

Tim Daneliuk tundra at tundraware.com
Thu Feb 16 14:45:19 PST 2006


Here is a shell function that behaves quite strangely:

#!/bin/sh
#####
# Execute A Command, Noting Start/Stop Time, & Logging Output
# Args:
#       $1 Command Name
#       $2 Log Directory
#       $3 Command String To Execute
#####

runupd()
{
       log=$2/$1.log
       timestamp $log
       touch $2/.$1-begin && eval $3 2>&1 >> $log && touch $2/.$1-end &
}

# End of 'runupd()'

So, you might do something like:

    runupd freespace /var/log/ "df -k"


Now, for the weirdness.  This function works fine in my script
so long as one of two conditions is met:

    1) I run it interactively from the command line (bash)
                       OR
    2) I run it from 'cron' AND $3 is *not* another script

If I try to run it from 'cron' and point $3 to a script, everything gets
run as planned, however, the ending timestamp (touch $2/.$1-end) never
runs. That is, the initial time stamp (.$1-begin) and the command itself
are executed, and output is properly written to the logfile,
but the final timestamp never happens.

I have been fiddling with this on- and off and cannot seem to explain
the behavior. I',m guessing that something about the combination of
'cron'and the 2>&1 >> $log business is causing the last touch to never
get invoked, but for the life of me, I cannot figure this one out.

Interestingly, this works fine in Linux (SuSE 10.0).  In Linux, both
'sh' and 'bash' are the same binary (bash is running as sh).  So ..
I went back to FreeBSD (4.x in this case, though the problem is also
noted in 6.x) and changed the SHELL variable in the crontabs file to
use 'bash' - same problem.

This is starting to feel like a problem with file handles getting clobbered
in the FreeBSD exec logic.

Other explanations welcome...
-- 
----------------------------------------------------------------------------
Tim Daneliuk     tundra at tundraware.com
PGP Key:         http://www.tundraware.com/PGP/




More information about the freebsd-questions mailing list