English 中文(简体)
How do I check the exit code of a command executed by flock?
原标题:

Greetings all. I m setting up a cron job to execute a bash script, and I m worried that the next one may start before the previous one ends. A little googling reveals that a popular way to address this is the flock command, used in the following manner:

flock -n lockfile myscript.sh
if [ $? -eq 1 ]; then
    echo "Previous script is still running!  Can t execute!"
fi

This works great. However, what do I do if I want to check the exit code of myscript.sh? Whatever exit code it returns will be overwritten by flock s, so I have no way of knowing if it executed successfully or not.

最佳回答

It looks like you can use the alternate form of flock, flock <fd>, where <fd> is a file descriptor. If you put this into a subshell, and redirect that file descriptor to your lock file, then flock will wait until it can write to that file (or error out if it can t open it immediately and you ve passed -n). You can then do everything in your subshell, including testing the return value of scripts you run:

(
  if flock -n 200
  then
    myscript.sh
    echo $?
  fi
) 200>lockfile
问题回答

According to the flock man page, flock has a -E or --exit-conflict-code flag you can use to set what the exit code of flock should be in the case a conflict occurs:

     -E, --conflict-exit-code number
              The exit status used when the -n option is in use, and the conflicting lock exists, or the -w option is in use, and the timeout is reached.  The default value is 1.  The number has to be in the range of 0 to 255.

The man page also states:

EXIT STATUS 
 
The command uses sysexits.h exit status values for everything, except when using either of the options -n or -w which report a failure to acquire the lock with a exit status given by the -E option, or 1 by default.  The exit status given by -E has to be in the range of 0 to 255.

When using the command variant, and executing the child worked, then the exit status is that of the child command.

So, in the case of the -n or -w flags while using the "command" variant, you can see both exit statuses.

Example:

$ flock --exclusive /tmp/flock.lock bash -c  exit 42 ; echo $?
42

$ flock --exclusive /tmp/flock.lock flock --exclusive --nonblock --conflict-exit-code 100 /tmp/flock.lock bash -c  exit 42 ; echo $?
100

In the first example, we see that we get back the exit status of the process we re running with flock. In the second example, we are creating contention for the lock. In that case, flock itself returns the status code we tell it (100). If you do not specify a value with the --conflict-exit-code flag, it will return 1 instead. However, I prefer setting less common values to prevent confusion from other processess/scripts which also might return a value of 1.

#!/bin/bash

if ! pgrep myscript.sh; then
  flock -n lockfile myscript.sh
fi

If I understand you right, you want to make sure myscript.sh is not running before cron attempts to run your command again. Assuming that s right, we check to see if pgrep failed to find myscript.sh in the processes list and if so we run the flock command again.

Perhaps something like this would work for you.

#!/bin/bash
RETVAL=0
lockfailed()
{
        echo "cannot flock"
        exit 1
}
(
        flock -w 2 42 || lockfailed
        false
        RETVAL=$?
        echo "original retval $RETVAL"
        exit $RETVAL
) 42>|/tmp/flocker
RETVAL=$?
echo "returned $RETVAL"
exit $RETVAL




相关问题
Parse players currently in lobby

I m attempting to write a bash script to parse out the following log file and give me a list of CURRENT players in the room (so ignoring players that left, but including players that may have rejoined)...

encoding of file shell script

How can I check the file encoding in a shell script? I need to know if a file is encoded in utf-8 or iso-8859-1. Thanks

Bash usage of vi or emacs

From a programming standpoint, when you set the bash shell to use vi or emacs via set -o vi or set -o emacs What is actually going on here? I ve been reading a book where it claims the bash shell ...

Dynamically building a command in bash

I am construcing a command in bash dynamically. This works fine: COMMAND="java myclass" ${COMMAND} Now I want to dynamically construct a command that redirectes the output: LOG=">> myfile.log ...

Perform OR on two hash outputs of sha1sum

I want perform sha1sum file1 and sha1sum file2 and perform bitwise OR operation with them using bash. Output should be printable i.e 53a23bc2e24d039 ... (160 bit) How can I do this? I know echo $(( ...

Set screen-title from shellscript

Is it possible to set the Screen Title using a shell script? I thought about something like sending the key commands ctrl+A shift-A Name enter I searched for about an hour on how to emulate ...

热门标签