Skip to content
Advertisement

Why does flock removes existing text from a file?

So, I am trying to get an exclusive lock on a text file using Flock and a line of text to that file however while doing so it removes whatever text was there earlier.

( flock -n 200 || exit 1
echo "In critical section"
echo text >> file.txt
echo text added to file 
) 200>file.txt
echo "After critical section"

So if the file had let’s say

123
214
242
232

and after running the script I am expecting something like

123
214
242
232
text

instead, all I get is

text

why would it behave like this, my guess is that it is replacing the original file but I am not sure.

Advertisement

Answer

  • stdout (fd 1) is not redirected to (fd 200), echo commands are written to stdout.

  • 200>file.txt truncates the file.txt before commands in subshell are executed

  • echo text >> file.txt appends text

using >> instead of > opens the file in append mode.

f() {
    (   flock -n 200 || exit 1
        echo "In critical section"
        echo text >> file.txt
        echo text added to file 
    ) 200>>file.txt
    echo "After critical section"
}

f & f & f & f ; wait

Note that the open (truncate/append) in outside of critical section.

Otherwise to block until lock is available don’t use -n, compare

f_fail() {
    (
        sleep 1
        flock -n 200 || exit 1
        pid=$(bash -c 'ps -p "$(ps -p $$ -oppid=)" -oppid=')
        echo "$pid started"
        echo text >& 200
        echo "$pid done"
    ) 200>>file.txt
}

f_block() {
    (
        sleep 1
        flock 200 || exit 1
        pid=$(bash -c 'ps -p "$(ps -p $$ -oppid=)" -oppid=')
        echo "$pid started"
        echo text >& 200
        echo "$pid done"
    ) 200>>file.txt
}


f_fail  & f_fail  & f_fail  & f_fail  & wait
f_block & f_block & f_block & f_block & wait
Advertisement