переименование файла на ext3, кажется, нарушает спецификации POSIX - PullRequest
2 голосов
/ 02 марта 2012

Я изо всех сил пытаюсь понять, что происходит в тесте, который я запускаю. Test - это два сценария оболочки, запущенные на одном компьютере.

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

Итак, я запускаю A / ext3_dir, а затем запускаю B / ext3_dir> out (поэтому в std out выходят только ошибки).

Это все работает нормально и, как и ожидалось, согласно спецификации POSIX для 'rename':

Если ссылка, названная новым аргументом, существует, она должна быть удалена, а старая переименована в новую. В этом случае ссылка с именем new должна оставаться видимой для других процессов на протяжении операции переименования и указывать либо на файл, на который ссылается new, либо на старый до начала операции.

Однако, если я добавлю жесткую ссылку на временный файл перед выполнением перемещения:

    #!/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; 

Я получаю ошибки "Нет такого файла или каталога" на стороне чтения - по-видимому, в нарушение спецификации POSIX.

Может ли кто-нибудь пролить свет на это поведение? Тест действителен? Я не могу понять, почему создание дополнительной ссылки на файл, который я перемещаю, должно влиять на способность читать из места назначения перемещения.

Ответы [ 2 ]

2 голосов
/ 07 марта 2012

Оказывается, это была известная проблема в некоторых версиях Redhat:

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

0 голосов
/ 05 марта 2012

Я запустил его в Debian, и он отлично работал в файловой системе EXT3.Я не вижу здесь ничего, что не должно работать.Я переписал цикл для оболочки SH, чтобы проверить его с минимальным сценарием.

#!/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

В любом случае, touch target не должно быть touch $1/target?

...