LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   flock - script done but still locked (https://www.linuxquestions.org/questions/linux-software-2/flock-script-done-but-still-locked-4175556951/)

ralfbutler 10-23-2015 05:09 AM

flock - script done but still locked
 
Hi,

at the beginning of my bash script I run flock to ensure that the script is not run twice at the same time.
Part of the scrip is to show xclock, but as background command. So I see the clock and the script finishes (the clock is still displayed oviously). But when I want to restart the script it doesn't allow me to do so because it is still locked. It seems that the lock is removed only when xclock is closed.

What I don't understand is why the lock remains when I start the x-app as background process and the script finishes. Is the x-app process a child of the process which executes the script?

I would very much appreciate if someone could explain this?

Thanks,
Ralf

berndbausch 10-23-2015 06:02 AM

Can you share how you are using flock?

ralfbutler 10-23-2015 06:10 AM

Here you go ...

#!/bin/bash

fd=200
eval "exec $fd>/tmp/test.lock"
if flock -n $fd; then
xclock &
else
echo "locked"
fi

ralfbutler 10-23-2015 05:27 PM

Anyone able to help out?

ondoho 10-24-2015 04:55 AM

not exactly.

i had a similar requirement once, and i don't remember why, but flock didn't do the trick for me and i decided on a simple selfmade function:
Code:

me="$(basename "$0")"

function only_me_or_exit {
    # make sure only 1 instance is running
    touch "$1"
    read lastPID < "$1"
    # if lastPID is not null and a process with that pid exists , exit
    [ ! -z "$lastPID" -a -d /proc/$lastPID ] && { echo "An instance of $me is already running with pid $lastPID." ; usage ; exit 1 ; }
    # else - save my pid in the lock file, and continue
    echo $$ > "$1"
}

pidfile="$tmp_dir/${me}_pid"
only_me_or_exit "$pidfile"

... actual script here ...


ralfbutler 10-24-2015 06:35 AM

Code I received as reply from another forum:

Code:

#!/bin/bash

fd=200
eval "exec $fd>/tmp/test.lock"
if flock -n $fd; then
  eval "xclock $fd>&- &"
else
  echo "locked"
fi

Works :-)

jpollard 10-24-2015 07:20 AM

Quote:

Originally Posted by ralfbutler (Post 5439283)
Anyone able to help out?

Yes. The problem is that you have an open file descriptor for the lock.

That file descriptor is then passed to xclock as part of its environment - though it isn't used by xclock.

The lock remains until the file descriptor is closed by all processes that have it open - which happens when xclock exits.

Thus the lock remains after the script has terminated.

The "working" version closes the file descriptor before invoking xclock - the way that happens is a side effect of the "eval" (new process, and then it closes the descriptor, then execs xclock).

sundialsvcs 10-24-2015 07:43 AM

Another pragmatic solution "allows a slight race-condition," knowing that such a condition will never actually occur. Simply see if a temporary file exists, do your stuff, remove the file and launch. Unless there is a serious possibility that two instances of this really are "running neck-and-neck," this is adequate.

Yet another strategy would be to execute xclock && rm lockfile which causes the forked shell to execute two commands in sequence: first, the clock, then removal of the lockfile. The command which launches this, does not remove the lockfile (unless the exec fails).

debguy 10-26-2015 02:11 PM

mail file lock (if you found flock as in sendmail package) are infamous for not working and only work when used by knowledgable programs in specific ways: used at commandline they DO NOT work.

make or remove a file on disk, check existence. "spin-lock" is the only easy relatively fast way you can resolve it. be wary that multiple threads checking and removing file wont work: only one thread can have the job or they will overlap / clobber each other.

another way is to use date(1) to check time, but time can change (by various settings, during boot, battery failure, update, etc) so be wary of that

using "c language" and if you have "newer kernel" their are new ways to lock access to a file to prevent other programs from writing/creating the same - however your using bash.

debguy 10-26-2015 02:14 PM

homework: look for "spin lock" in kernel code. it's all about "loggin in" data on disk, whether data has actually hit the disk physically (and has no pending request for removal).

if data is on the disk "for sure without a doubt" it is "logged in" and "spin lock" is achieved (more generally spin lock is achieved if the status is finalized, no buffered requests in memory exist, ie no open files swapped or no applications have open write status pending, status is fully flushed no memory or disk caching or signals requests are pending as to hardware read/write on a physical part of the disk)

debguy 10-26-2015 02:16 PM

maybe use two status files (editing status, done status) if needed

anyway dont use flock(1) if its the one that's been in distros for many years: far more easy to do it yourself i guarantee you


All times are GMT -5. The time now is 09:01 PM.