Как запретить удаление (но не создание) элементов в папке?

Как запретить удаление (но не создание) элементов в папке?

В моей домашней директории создается папка, и я хочу проанализировать содержимое этой папки, однако у меня возникла проблема: как только папка создается, она тут же удаляется той же программой, которая ее создала. Есть ли способ разрешить ей создать папку, но не удалять ее? Я использую Ubuntu GNOME 15.10 с GNOME 3.18.

решение1

Нет никаких настроек разрешений, которые могли бы это сделать, даже с использованием ACL, но вы можете устроить гонку с программой, используя inotifywait:

В одном терминале я запустил:

while sleep 0.5; do if mkdir foo/bar; then echo foo; rmdir foo/bar; fi; done

Как видите, это создает каталог, отображает сообщение и удаляет каталог — все это происходит очень быстро по человеческим меркам.

И в другом:

while true
do
    if inotifywait -e create foo
    then
        chmod -w foo
        if [[ -d foo/bar ]]
        then
            break 
        else
            chmod +w foo
        fi
    fi
done

Эта команда ждет создания чего-либо в foo, затем удаляет разрешения на запись из fooи проверяет, успела ли она поймать подкаталог. Если нет, она возвращает разрешение на запись и начинает снова.

Немного подождав:

foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
rmdir: failed to remove ‘foo/bar’: Permission denied
mkdir: cannot create directory ‘foo/bar’: File exists
mkdir: cannot create directory ‘foo/bar’: File exists
mkdir: cannot create directory ‘foo/bar’: File exists
mkdir: cannot create directory ‘foo/bar’: File exists

Это основано насостояние гонки, так что сможете ли вы его поймать — это вопрос удачи.


foo/barэто каталог, который создает программа. Если вы не знаете его имени, вы можете попробовать другие способы:

  • убедитесь, что в каталоге больше ничего нет, поэтому при создании подкаталога foo/он непустой. Некоторые тесты для непустого каталога доступны вэтот пост U&L:

    shopt -s nullglob
    if [ -n "$(ls -A foo/)" ]
    then
        break
    

    Это сработало достаточно быстро.

  • прочитайте имя созданного каталога из inotifywaitвывода:

    if dir=$(inotifywait -e create --format '%f' foo)
    then
        chmod -w foo
        if [[ -d foo/$dir ]]
    

    Это не сработало (пока) для меня; накладные расходы на создание подоболочки, похоже, делают его достаточно медленным, чтобы другой цикл выигрывал каждый раз. Возможно, закодированное на C с использованием API inotify, это могло бы сработать.

Связанный контент