Предотвратить удаление файла даже после rm -f

Предотвратить удаление файла даже после rm -f

Я обычно сижу на StackOverflow, но думаю, что в этой теме вы, ребята, гораздо более компетентны.

Итак, сегодняшнее упражнение странное: мне нужно написать script.shи в нем сделать все возможное, чтобы предотвратить test.txtудаление, но загвоздка в том, что последняя строкаимеетбыть

rm -f test.txt

Я не очень хорошо разбираюсь в shell (обычно я использую c/objective-c), поэтому я взял книгу, не дочитал ее, но до сих пор не имею ни малейшего представления, как это сделать.

Я думал о разрешениях, но скрипту будут предоставлены все разрешения при тестировании, так что это не вариант... (Не знаю, имеет ли это значение, но скрипт будет запущен на OS X).

решение1

В Linux вы можете использовать флаг immutable, chattrчтобы получить доступ только для чтения на уровне файловой системы (хотя для этого требуются соответствующие разрешения). Я не использую OS X и не знаю, есть ли там что-то подобное, но вы можете добиться "после запуска скрипта, test.txtвсе еще существовать" с помощью:

#!/bin/sh
mv test.txt test.bak
trap "mv test.bak test.txt" EXIT

rm -f test.txt

Этот скрипт переименовывает test.txtв test.bakи переименовывает его обратно, когда скрипт завершает работу (после rm -f test.txt). Это не совсем только для чтения, но если вы не используете kill -KILLсвой скрипт, он должен по крайней мере сохранить ваши данные.

Альтернативная идея: если вы настаиваете на наличии этой строки, почему бы не выйти пораньше?

#!/bin/sh
# do your thing
exit
# my boss insisted to have the 'rm' line below.

rm -f test.txt

Альтернатива, которая превращается rmв функцию, которая ничего не делает:

#!/bin/sh
# do your thing
rm() {
    # this function does absolutely nothing
    : # ... but it has to contain something
}

rm -f test.txt

Аналогично методу функции, описанному выше, но с использованием устаревшей aliasкоманды в качестве псевдонима rmдля trueвстроенной функции, которая ничего не делает (но возвращает настоящий код выхода):

#!/bin/sh
# do your thing
alias rm=true

rm -f test.txt

Альтернатива, которая удаляет rmиз среды (предполагая, что нет rmвстроенных):

#!/bin/sh
# do your thing
PATH= # now all programs are gone, mwuahaha

# gives error: bash: rm: No such file or directory
rm -f test.txt

Еще один вариант, который изменяется $PATHс помощью rmпрограммы-заглушки (используя /tmpв качестве пути поиска):

#!/bin/sh
# do your thing
>/tmp/rm # create an empty "rm" file
chmod +x /tmp/rm
PATH=/tmp

rm -f test.txt

Для получения дополнительной информации о встроенных модулях запустите help <built-in>for details. Например:

true: true
    Return a successful result.

    Exit Status:
    Always succeeds.

Для получения информации о других командах используйте man rmили посмотрите страницу руководства man bash.

решение2

Для удаления файла требуются права на запись в каталог, содержащий этот файл.

$ chmod -w .
$ rm -f test.txt
rm: cannot remove `test.txt': Permission denied

Вероятно, вам следует сделать это во временном каталоге, созданном специально для этой цели; например, вы не хотите удалять разрешение на запись в вашем домашнем каталоге, хотя это достаточно легко восстановить с помощьюchmod +w .

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