David Sankovsky
asked on
Check if a filw is immutable for a certain amount of time
Hi Guys,
I'm trying to automate a certain process that I'm working on.
To make sure that the file I'm working on right now isn't altered while I'm working on it, I set it as immutable in the beginning of the script and release it when the script ends (Script usually runs for approximately 17 seconds.
However, since the workflow allows in somecases for multiple instances of the script to run, I don't want the 2 instance to throw an error straight away, I'd like the script to check the the file in question is locked for over 30 senconds and only then die
the if line is fairly easy..
it's the rest of the test block I'm having trouble with
any ideas?
I'm trying to automate a certain process that I'm working on.
To make sure that the file I'm working on right now isn't altered while I'm working on it, I set it as immutable in the beginning of the script and release it when the script ends (Script usually runs for approximately 17 seconds.
However, since the workflow allows in somecases for multiple instances of the script to run, I don't want the 2 instance to throw an error straight away, I'd like the script to check the the file in question is locked for over 30 senconds and only then die
the if line is fairly easy..
if [ lsattr "/scripts/test.file" | cut -c 5 | fgrep -q 'i' ]
it's the rest of the test block I'm having trouble with
any ideas?
flock can do this for you. I expect you are using it already, but perhaps you are using something else to make the file immutable. You need to wrap the script's top-level commands in a main() function (any name will do) (top-level means not in a function already). You do it like this (no file locking yet)
To run your script with the file locked, change the last line and add error handling
#!/bin/sh
main()
{
# top-level logic goes here
}
# Start the show
main "$@"
Note that the last line of your script invokes main. You can define other functions in any order you choose and they can call each other, because [ba]sh has read them all in before trying to execute any of them.To run your script with the file locked, change the last line and add error handling
# Start the show
flock -w 30 -E 4 "/scripts/test.file" main "$@"
retcod=$? # Capture return code from main (if flock succeeded) else 4 from flock
[ $retcod -ne 4 ] || { echo "Timed out waiting for lock" >&2; exit 1; }
# Check retcod for other errors here if you wish
Error code 4 is an arbitrary choice. You want to use a number that main() cannot return
Oops - the above solution doesn't work: flock can't execute main (new shell process).
Never mind, you just need to have 2 scripts: one with flock and the second executed by flock
Never mind, you just need to have 2 scripts: one with flock and the second executed by flock
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you both, You helped me with my script a lot :)
The script supplied runs when the lock is acquired, that lock should kill itself to free the lock.
From man flock
NAME
flock - manage locks from shell scripts
SYNOPSIS
flock [options] file|directory command [arguments]
flock [options] file|directory -c command
flock [options] number
DESCRIPTION
This utility manages flock(2) locks from within shell scripts or from the command line.
The first and second of the above forms wrap the lock around the execution of a command, in a manner similar to su(1) or new-
grp(1). They lock a specified file or directory, which is created (assuming appropriate permissions) if it does not already
exist. By default, if the lock cannot be immediately acquired, flock waits until the lock is available.
The third form uses an open file by its file descriptor number. See the examples below for how that can be used.