Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux flock, how to "just" lock a file?

Tags:

In Bash, I'm trying to make a function getLock to be used with different lock names.

function getLock {     getLock_FILE="${1}"     getLock_OP="${2}"     case "${getLock_OP}" in         "LOCK_UN")             flock -u "${getLock_FILE}"             rm -fr "${getLock_FILE}"             ;;         "LOCK_EX")             flock -x "${getLock_FILE}"     esac } 

But flock says flock: bad number: myfilelock

How can I just lock a file, and release it when I want, without having to execute a command in the flock?

It is to be used like this:

getLock myfilelock LOCK_EX somecommands ........ getLock myfilelock LOCK_UN 
like image 874
JorgeeFG Avatar asked Jun 24 '14 13:06

JorgeeFG


People also ask

How do you lock a flock file?

Lock a Text File Using Linux's flock UtilityThe -x option is for obtaining a write lock to the targeted file. Let us attempt to lock the sample output. txt text file. The -c option will enable us to pass a single Linux supported command e.g. cat command.

What is flock lock?

Locking files with flock. One common way to lock a file on a Linux system is flock . The flock command can be used from the command line or within a shell script to obtain a lock on a file and will create the lock file if it doesn't already exist, assuming the user has the appropriate permissions.

Where is lock file in Linux?

Lock files should be stored within the /var/lock directory structure. Lock files for devices and other resources shared by multiple applications, such as the serial device lock files that were originally found in either /usr/spool/locks or /usr/spool/uucp , must now be stored in /var/lock .


1 Answers

To lock the file:

exec 3>filename # open a file handle; this part will always succeed flock -x 3      # lock the file handle; this part will block 

To release the lock:

exec 3>&-       # close the file handle 

You can also do it the way the flock man page describes:

{   flock -x 3   ...other stuff here... } 3>filename 

...in which case the file is automatically closed when the block exits. (A subshell can also be used here, via using ( ) rather than { }, but this should be a deliberate decision -- as subshells have a performance penalty, and scope variable modifications and other state changes to themselves).


If you're running a new enough version of bash, you don't need to manage file descriptor numbers by hand:

# this requires a very new bash -- 4.2 or so. exec {lock_fd}>filename  # open filename, store FD number in lock_fd flock -x "$lock_fd"      # pass that FD number to flock exec $lock_fd>&-         # later: release the lock 

...now, for your function, we're going to need associative arrays and automatic FD allocation (and, to allow the same file to be locked and unlocked from different paths, GNU readlink) -- so this won't work with older bash releases:

declare -A lock_fds=()                        # store FDs in an associative array getLock() {   local file=$(readlink -f "$1")              # declare locals; canonicalize name   local op=$2   case $op in     LOCK_UN)       [[ ${lock_fds[$file]} ]] || return      # if not locked, do nothing       exec ${lock_fds[$file]}>&-              # close the FD, releasing the lock       unset lock_fds[$file]                   # ...and clear the map entry.       ;;     LOCK_EX)       [[ ${lock_fds[$file]} ]] && return      # if already locked, do nothing       local new_lock_fd                       # don't leak this variable       exec {new_lock_fd}>"$file"              # open the file...       flock -x "$new_lock_fd"                 # ...lock the fd...       lock_fds[$file]=$new_lock_fd            # ...and store the locked FD.       ;;   esac } 

If you're on a platform where GNU readlink is unavailable, I'd suggest replacing the readlink -f call with realpath from sh-realpath by Michael Kropat (relying only on widely-available readlink functionality, not GNU extensions).

like image 95
Charles Duffy Avatar answered Oct 13 '22 01:10

Charles Duffy