Quote:
Originally Posted by blrguest
I would like to know is there any possibility to get consistent output like log file (/var/log/message) for any number of time script invocation.
|
Yes, use the
flock (man 1 flock) command from the util-linux-ng package.
Since you wish to log multi-line reports -- I'm assuming as the script progresses, which may take a bit of time -- I'd recommend using a temporary file to store all output of the script, and append it to the actual log only when the script exits. That way the log file is only locked for the short moment it takes to append it. The
trap bash built-in is perfect for this. In this example code, I used a five-second timeout for the lock: if it cannot lock the log file in five seconds, it will append its log without the lock.
Code:
#!/bin/bash
LOGFILE="/tmp/ZZ/OUT"
# Create a safe temporary directory $WORK for temporary files.
# $WORK/log is appended to $LOGFILE when the script exits, using flock(1).
# Finally, $WORK and all its contents are removed when the script exits;
# you can use $WORK for any and all other temporary files you might need.
WORK="`mktemp -d`" || exit $?
trap "flock -e -w 5 '$LOGFILE' bash -c 'cat \"$WORK/log\" >> \"$LOGFILE\" ; echo \"-----------------------\" >> \"$LOGFILE\"' || bash -c 'cat \"$WORK/log\" >> \"$LOGFILE\" ; echo \"-----------------------\" >> \"$LOGFILE\"'; rm -rf '$WORK'" EXIT
# Redirect output and error to $WORK/log.
exec &>"$WORK/log"
# Now your script can do it's work. No other commands are needed,
# the above code will take care of everything.
echo "This is process $$ at `date`."
sleep 1
echo "Hello"
sleep 1
echo "World"
Since the
trap command is a bit hard to parse, here's the command it runs when the script exits:
Code:
flock -e -w 5 '$LOGFILE' \
bash -c ' cat \"$WORK/log\" >> \"$LOGFILE\"
echo \"-----------------------\" >> \"$LOGFILE\"
' \
|| bash -c ' cat \"$WORK/log\" >> \"$LOGFILE\"
echo \"-----------------------\" >> \"$LOGFILE\"
' ; \
rm -rf '$WORK'
The
flock command will fail if it cannot get the write lock (
-e for exclusive lock) within the five-second timeout (
-w 5). If it gets the lock, it'll cat the temporary log file to the actual log file, and append a horizontal line. If
flock fails, the exact same command is run -- I assume you'd rather have messed output than none at all, if something weird happens. But remember,
flock will usually get the lock, and that is what prevents the processes from messing with each others output.
Hope this helps.