
Я обычно сижу на 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 .