2

My script makes flock. This prevents me for runing its twice. Script can execute another script, and there is a problem. Sometimes another scripts leaves processes in background. Unfortunately they inherits flocks, I don't need this. Is it any wraper who close some file handles before execute specified executable?

I use linux debian, but it isn't impornant linux distro or version.

Detailed scenario:

  1. My script A is run
  2. My script A makes flock
  3. My script A runs external executable B
  4. External B runs executable C as background (inherit flock)
  5. External B finishes and leaves C in background (inherit flock)
  6. My script A finishes because B finishes
  7. Another loop, My script A is run (as point 1)
  8. My script A makes flock and fail, because C still is running

I want exactly run external executable B with closed flocked filehandle. Flock should be keeped until only my script A is running. I don't want close flock between 2 and 3 points, because there will be "flock hole". Is there any wrapper os something like this?

3

3 Answers 3

2

According to flock's man page, this is one use of the -u or --unlock option:

-u, --unlock

Drop a lock. This is usually not required, since a lock is automatically dropped when the file is closed. However, it may be required in special cases, for example if the enclosed command group may have forked a background process which should not be holding the lock.

The prescribed technique is therefore something like this:

(
    flock 200 | exit 99
    # some commands that should be guarded by the lock
    # some of them fork daemons that keep our lock file open
    flock --unlock 200 # we're done with the lock, we can release it
) 200>/path/to/lock-file
1
  • You're right. When process forks or run another process, it inherits flock with his parent. All processes in child tree should finish for leave flock. When script goes into non critical phase and it will take long time, flock should be freed. It is related to called commands also. when that commands are independed to main process, flock should be freed as in situation described before.
    – Znik
    Commented Apr 20, 2016 at 12:16
2

The following code acquires the lock and the trap ensures it is released when the script exits. The child processes inherit the lock but do not keep it acquired after flock --unlock 200 executes.

flock 200 | exit 1
trap "flock --unlock 200" EXIT
# The rest of the script...

Note: Only 1 trap may be in effect at a time. If you need to execute multiple commands in an exit trap, then you need to put them in a method or combine them as such trap "flock --unlock 200; echo Bye" EXIT.

0

I wrote some wrapper yesterday. It closes all unneeded handles, then call specified command. Unfortunately it doesn't check handle type, closes all escept some known handles.

<==== file: wrapper.sh ====>
#!/bin/bash
for fd in $(ls /proc/$$/fd); do
 case "$fd" in
  0|1|2|255)
 ;;
 *)
  eval "exec $fd>&-"
 ;;
 esac
done
exec $1 $2 $3 $4 $5 $6 $7 $8 $9

you cal this by:

wrapper.sh some_command command parameters

I can use this warapper at step 3 on my call scenario. Then flock exists inside main script only, and wrapper breaks inheritation in called script and his children.

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .