Версия последней (по состоянию на 2017 г.) в спецификации POSIX для rm
утилиты здесь (и предыдущий там ) и запрещает удаление .
и ..
.
Если любой из файлов точка или точка-точка указана в качестве части базового имени операнда (то есть конечного компонента имени пути) или если операнд преобразуется в корневой каталог, rm должен записать диагностическое сообщение в стандартную ошибку и ничего не делать больше с такими операндами.
Как отмечает @jlliagre, часть о /
дополнении в SUSv4.
Самая старая общедоступная спецификация Unix, которую я смог найти ( XPF4 CAE rev2 (1994)), уже указала это .
и ..
не может быть удалена, хотя комментарии в журнале изменений GNU fileutils предполагают, что это уже имело место в более старых спецификациях POSIX.
Обратите внимание, что это относится и к, dir/..
и ../
к тому же, но некоторые реализации (включая UNIX-сертифицированные, такие как Solaris 11 и macOS) все еще не защищают от rm -rf ../
или rm -rf .*/
).
история
Ранние объединения
-r
Опция rm
была добавлена в Unix V3 (1973) , хотя это было только удаление содержимого каталогов, вам все равно нужно использовать rmdir
для удаления каталогов.
Это изменилось в Unix V7 (1979, выпуск, который также представил оболочку Bourne и из которой происходит большинство Unices). rm -r
теперь также удаляются каталоги и не будут удалять ..
дерево каталогов. На странице руководства государства:
Запрещается удалять файл ..
только для того, чтобы избежать антисоциальных последствий непреднамеренного совершения чего-либо подобного rm -r .*
.
(хотя можно утверждать, что rm -r .*
это антисоциально, поскольку удаляет все, потому что .
включено).
Он все же согласился удалить, .
хотя он не отменял связь .
ни с ..
записями, ни с. Итак, rm -r .
был эффективный способ очистить текущий каталог.
Также обратите внимание, что гарантия была только для буквального ..
аргумента, а не для dir/..
или ./..
. Таким образом, rm -rf ./.*
все равно все рекурсивно удаляется из родительского каталога.
Интересно видеть, что это было уже для обхода ошибки / ошибочной характеристики, которую глобусы могли включать .
и ..
в их расширение. Это было исправлено в оболочке Forsyth (основа для оригинальной оболочки Minix и pdksh) в конце 80-х zsh
(1990) и fish
(2005), но не в других оболочках и, в частности, не в sh
языке POSIX, который требует расширения .*
для включения .
и, ..
если они возвращаются readdir()
( bash
решает проблему частично только в shopt -s dotglob
тех случаях, когда глобусы (кроме .xxx
тех) не включают .
или ..
, и, с помощью ksh
, вы можете исправить это, выполнив FIGNORE='@(.|..)'
).
Когда .
было добавлено точное запрещение, это не всегда понятно и зависит от каждого Unix. Несколько выводов ниже.
BSDs
Запрещая из .
добавляли то между 2.9BSD (1983) и 2.10BSD (1987) , а также между 4.2BSD (1983) и 4.3BSD (1986) (см это изменение датируемые 1985 в unix-истории-репо ).
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9BSD/root.tar.gz |
zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `..'
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.10bsd.tar.gz |
zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `.' or `..'
rm: cannot remove `.' or `..'\n");
Для dir/.
и dir/..
см это изменение в 1988 году (BSD 4.3 Net / 1).
На данный момент rm
FreeBSD (и его производные, такие как macOS) по-прежнему очищают текущий или родительский каталог rm -rf ./
или rm -rf ../
хотя бы (имеет значение для rm -rf .*/
).
Система V
У меня не так много информации, так как ни исходный, ни двоичный файлы не доступны для производных AT & T Unix после V7. В своем электронном руководстве, HPUX ( на основе System III) до сих пор упоминает , что он только запрещает , ..
а эффективно это запрещает и что является свидетельством того, что , вероятно , по крайней мере , SysIII не запрещает удаление .
( редактирование : Теперь , глядя на в SysIII rm
исходном коде , это практически не изменился со времен Unix V7).
Все другие онлайн-руководства, которые я проверил, упоминают об удалении .
или ..
запрещении, которое, как ожидается, должно соответствовать POSIX.
Solaris по- rm
прежнему очищает текущий или родительский каталог после rm -rf ./
или rm -rf ../
.
GNU
Рано изменений для FileUtils GNU имеет всю историческую информацию.
Хотя первоначально ни удаление, .
ни ..
были запрещены, ..
сначала было запрещено, а затем оба (включая dir/.
), все в период с 1990 по 1991 год.
Другие
Как мы видели zsh
, расширение .*
(или любой глобус) никогда не включает .
или ..
(даже в sh
режиме эмуляции). Поэтому rm
встроенный (который вы получаете, если вы zmodload zsh/files
) не относится .
или ..
специально. Таким образом, с этим zsh
встроенным, вы можете rm -rf .
или rm -rf ..
очистить .
или ..
, но rm -rf .*
не удалит .
или ..
.
В busybox rm
запрет на удаление .
и ..
был добавлен в 0.52 (2001)
rm
, но я подумал , что это стоит отметить , что вы можете иметь неожиданные результаты сchmod
,chown
и т.д. при совмещении.*
.