Languages and Scripting
cancel
Showing results for 
Search instead for 
Did you mean: 

Locking files from a shell script

 
SOLVED
Go to solution
Highlighted
Regular Advisor

Locking files from a shell script

Dear all,

Who can help . . .
What command can create a file from a shell script, run as root, and gives no error if the creation succeeds but generates an errorlevel if the file already exists ??

touch does'nt
cat doesn't

What does . . .


Klaas Eenkhoorn
11 REPLIES 11
Highlighted
Regular Advisor

Re: Locking files from a shell script

Sorry the subject is a bit misleading . . .
The command shoud be used for a sort of locking mechanism based on the exsistance of a file.

a construction of
if [ -f file]
then
wait_for_compleation
else
touch file
do_something
rm file
fi

is to slow, during the time needed to get from the if -f to the touch statment some other proces, doning the same commandsequence, does the same action 'do_smomething' instead of waiting.

Kl@@s
Highlighted
Honored Contributor

Re: Locking files from a shell script

Klaas,
why don't you test for esistance of the file first ?

if [ -f filename ]
then
echo "file found"
else
echo "file not found"
fi

See "man test"

You could also try "mv -i", which will ask for permission, before overwriting an existing file.
Highlighted
Honored Contributor

Re: Locking files from a shell script

Hy

I would also try something like:

#!/usr/bin/ksh

filename=blah

if [ -a ${filename} ]
then
echo "file already exists"
else
touch ${filename}
fi

Regards
Highlighted
Honored Contributor

Re: Locking files from a shell script

Klass,
missed your additional post by 3 seconds, so my first post was based on initial description.

Unix places the detailed control over access to files on the programmer, so I think in your case, your application will have to open the file with read/write exclusive.

For example, root can vi a file and another session can remove the currently edited file, without warning. So if you quit your editor without saving, you have lost the whole file !
Highlighted
Honored Contributor

Re: Locking files from a shell script

Hi Klaas,

afaik, there is no shell command to exercise a file locking regime similar to the fcntl() syscall.
But such a thing possibly may exist, and simply has escaped my notice so far.
Anyway, even use of fcntl() would only implement "advisory locking" if I recall correctly, meaning that only another program that was equally written to be locking considerate would do so.
For shell scripts I think you will have to prescribe a simple logic that if a certain lock file exists the execution will be discontinued for a contending process.
You could look at init scripts for inspirations.
For instance many daemons store their pid in a file like /var/run/daemon_name.pid
whose existence prevents a second start of that process.
On linux they e.g. use the /var/lock/subsystem directory in a similar manner.
Madness, thy name is system administration
Highlighted

Re: Locking files from a shell script

I don't see anything better with Peter's and Oviwan's fragments. Perhaps they were answering the initial question?

You could do rm and check for errors. That's pretty atomic. ;-)

And perhaps a mkdir on another directory if the first test passes?

Perhaps for your initial question about root, using mkdir/rmdir will work consistently.
Highlighted
Regular Advisor

Re: Locking files from a shell script

Thanks all,

Well the file does not have to be locked the whole time.
Even its existance could be enough.

Is there someting like:

Command : create_file
errorlevel: 0 = file could be created
errorlevel: 1 = file allready exists

then the construction could be:

# check if if some process is working at this moment

create_file file
if [ $? -eq 0 ]
then
do_my_thing
rm file
else
wait_for_other_process
fi

Kl@@s




Highlighted
Occasional Visitor
Solution

Re: Locking files from a shell script

My suggestion is to use 'ln -s'

The command is exclusive (e.g. if the file already exists, a failure occurs) and is done in a single step (e.g. there is no if else statement). This should eliminate your contention problem.

Cheers,
BYG.
Highlighted
Occasional Visitor

Re: Locking files from a shell script

Sorry. Found myself being ambiguous. The following example should make things clear:

ln -s whatever lockfile
if [ $? -eq 0 ]; then
do what you need to do
else
throw some error
fi

Or you could wrap the whole thing within a function and test the result of the function to do what needs to be done:
file_lock () {
dowhat="$1"
lockfile="$2"
case "$dowhat" in
lock)
ln -s whatever $lockfile
return $?
;;
unlock)
rm -f $lockfile
;;
*)
echo "What's this?"
return 1
;;
esac
}

Allows for more flexibility in that you can lock/unlock with the same function and establish the name of the file you want to lock with.