Home > OS >  what does "if { set -C; 2>/dev/null >~/test.lock; }" in a bash mean?
what does "if { set -C; 2>/dev/null >~/test.lock; }" in a bash mean?

Time:10-12

I have encountered this in a bash script:

if { set -C; 2>/dev/null >~/test.lock; }; then
    echo "Acquired lock"
else
    echo "Lock file exists… exiting"
    exit 1
fi

It enters on the else flow. I know set -C will not overwrite the files, 2>/dev/null means something as : redirect errors to "void", but then I have >~/test.lock and will mean to redirect something in the lock file, (what exactly, the errors probably). I have test.lock the file in home, created, and empty. Being a if , it must return false in my case.

CodePudding user response:

{ ... ; ... ; } is a compound command. That is bash executes every command in it, and the exit code is the one of the last one. It is a bit like ( ... ; ... ), except that with ( you execute a subshell (a bit like sh -c "... ; ...") which is less efficient, and, moreover, prevent affecting local variables of your current shell, for example.

So, in short, { set -C; 2>/dev/null >~/test.lock; } means "do set -C, then do 2>/dev/null >~/test.lock and the return (exit code) is the one of that last command".

So if { set -C; 2>/dev/null >~/test.lock; } is "if 2>/dev/null >~/test.lock succeeds in that compound command, that is after set -C".

Now, set -C means that you can't overwrite existing files

And 2>/dev/null > ~/test.lock is an attempt to overwrite test.lock if it exists, or to create it if it doesn't.

So, what you have here, is

  • If lock file already exist, fail and say "lock file exists, exiting"
  • If lock file did not exit, create it, and say "lock acquired".

And it does it in one operation. So it is different than

# Illustration of how NOT to do it. Do not use this code :-)
if [[ -f "test.lock" ]]
then
    echo "lock file exists, exiting"
else
    2>/dev/null > ~/test.lock
    echo "lock file acquired"
fi

because that, clearer but wrong, version does not guarantee that something will have created the lock file between the evaluation of the if condition and the execution of 2>/dev/null > ~/test.lock.

The version you've shown has the advantage that the creation and test of lock is the same thing.

CodePudding user response:

set -C disallows writing to existing files

2>/dev/null suppresses warnings

>~/test.lock attempts to write to a file called test.lock. If the file already exists this returns an error because of set -C. Otherwise it will create a new test.lock file, making the next instance of this script fail on this step.

The purpose of lock files is to ensure that only one instance of a script runs at the same time. When the program is finished it could delete ~/test.lock to let another instance run.

  • Related