I am struggling to understand what is going on in a test I am running. Test is two shell scripts running on the same machine.

A:

    #!/bin/bash
    touch target;
    for ((i=0; i < 1000; i=i+1)); do
        echo "snafu$i" > $1/file$i;
        mv -f $1/file$i $1/target; 
    done; 

B:

    #!/bin/bash
    while(true);do 
        cat $1/target; 
    done

So I run A /ext3_dir, then run B /ext3_dir > out (so only errors go to std out).

This all works fine and as expected according to the POSIX spec for 'rename':

If the link named by the new argument exists, it shall be removed and old renamed to new. In this case, a link named new shall remain visible to other processes throughout the renaming operation and refer either to the file referred to by new or old before the operation began.

However if I add a hard-link to the temporary file before doing the move:

    #!/bin/bash
    touch target;
    for ((i=0; i < 1000; i=i+1)); do
        echo "snafu$i" > $1/file$i;
        ln $1/file$i $1/link$i
        mv -f $1/file$i $1/target; 
    done; 

I get "No such file or directory" errors on the reading side - seemingly in contravention of the POSIX spec.

Can anyone shed any light on this behaviour? Is the test valid? I can't figure out why creating an extra link to the file I'm moving should impact the ability to read from the move destination.

有帮助吗?

解决方案

It turns out this was a known problem on some redhat versions:

https://bugzilla.redhat.com/show_bug.cgi?id=438076

其他提示

I have run it on Debian, and it worked fine on EXT3 file system. I see nothing here that should not work. I rewrote the loop for SH shell, to test it with a minimal script.

#!/bin/sh
    touch target
    for i in $(seq 1 999) do
            echo "snafu$i" > $1/file$i;
            ln $1/file$i $1/link$i
            mv -f $1/file$i $1/target
    done

Anyway, that touch target shouldn't be touch $1/target?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top