Operating System - Linux
1827849 Members
1736 Online
109969 Solutions
New Discussion

Re: Locking files from a shell script

 
SOLVED
Go to solution
Klaas D. Eenkhoorn
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
Klaas D. Eenkhoorn
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
Peter Godron
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.
Oviwan
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
Peter Godron
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 !
Ralph Grothe
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
Dennis Handly
Acclaimed Contributor

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.
Klaas D. Eenkhoorn
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




Goh Boon Yeow
New Member
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.
Goh Boon Yeow
New Member

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.
Klaas D. Eenkhoorn
Regular Advisor

Re: Locking files from a shell script

Thanks,

The ln solution works for me !
Good thinking.

Thanks for the replies.

Kl@@s
dirk dierickx
Honored Contributor

Re: Locking files from a shell script

just for completion, it seems you are creating a script that can be called while the previous execution might still be running, but they cannot run at the same time.

the clean unix way is to use .pid files in the /var/run directory. this file contains the pid of the active running process.

this has several interesting advantages;
- you know there is (still) something running
- it is easy to kill, by just cating the pid file.
- all files are at one location
etc.