С каких это пор POSIX и GNU rm не удаляют /?


23

В течение нескольких лет rmутилита GNU не будет удалять, /если она не вызывается с --no-preserve-rootопцией. Тем не менее, команда rm -rf /в течение долгого времени находилась в коллективном подсознании как опасная, и люди до сих пор часто называют ее «страшной» командой.

Мне было интересно, когда появилось это правило, которое rmнельзя удалить /. Я проверил спецификации POSIX и вижу, что, хотя POSIX: 2008 включает в себя эту функцию безопасности, POSIX: 2001 не включает. Поскольку онлайн-версии спецификаций POSIX время от времени обновляются, с каждым новым дополнительным выпуском я также проверял машину возврата и находил соответствующую страницу POSIX: 2008 от 2010 года и смог подтвердить, что правило, которое rmне может удалить /был уже в списке тогда.

Итак, мои вопросы:

  • Когда было добавлено правило, которое rmнельзя удалить, /в спецификации POSIX? Было ли это в оригинальной редакции 2008 года Единой спецификации UNIX версии 4 или было добавлено в редакцию?
  • Когда это ограничение было добавлено в GNU rm? Я уверен, что это было до того, как он был добавлен в POSIX, но когда это случилось?


1
Связанный: Интерпретация Austin Group # 019 (2003), которая описала (но не осуществила) изменение.
Майкл Гомер

Ответы:


28

Вы можете найти HTML-версию всех выпусков POSIX 2008 онлайн:

Это было добавлено в выпуске 2008 года.

Технические исправления обычно не добавляют новые функции.

Вы можете видеть, что предыдущая версия ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/rm.html ) (POSIX 2004) не имела этого текста.

Новый текст был принят на конференции группы Остин 2003-05-09 для включения в более поздний пересмотр стандарта.

Это было запрошено Джоном Беком из Sun Microsystems в марте того же года (ссылка требует регистрации в открытой группе, см. Также запрос № 5 здесь ).

Джон Бек написал в вторник 11 марта 2003 года:

@ page 820 line 31681-31683 section rm comment {JTB-1}

Problem:

Defect code :  3. Clarification required

An occasional user mistake, with devastating consequences, is to
write a shell script with a line such as:
      rm -rf $VARIABLE1/$VARIABLE2
or
      rm -rf /$VARIABLE1
without verifying that either variable is set, which can lead to
      rm -rf /
being the resulting command.  Since there is no plausible
circumstance under which this is the desired behavior, it seems
reasonable to disallow this.  Such a safeguard would, however,
violate the current specification.

Action:

Either extend the exceptions for . and .. on the noted lines
to list / as well, or specify that the behavior of rm if an
operand resolves to / is undefined.

GNU rmдобавил --preserve-rootи --no-preserve-rootопции в этом коммите 2003-11-09 , но --preserve-rootстал только по умолчанию в этом коммите 2006-09-03 , поэтому в coreutils 6.2

FreeBSD сохраняет косую черту с момента коммита 2004-10-04журналом коммита «Узнай, насколько огнестойким на самом деле мое белье» ), но изначально не когда былPOSIXLY_CORRECT , пока они не вспомнили, что проверяли десятилетие спустя, что POSIX теперь поручив это в этот момент это было сделано также в режиме POSIX .

Первоначальный коммит FreeBSD упоминает, что Solaris уже делал это в то время.

@JdePB (в комментариях ниже) обнаружил, что эта ссылка на историю инсайдеров Sun подтверждает и дает более подробную информацию о происхождении Solaris и говорит о том, что Solaris уже имела защиту, прежде чем они обратились к группе Austin.

Это объясняет обоснование для добавления этого исключения. Хотя можно винить себя только в том случае, если они это делают rm -rf /, в одном случае сценарий мог бы сделать это, если бы rm -rf -- "$1/$2"не проверял, что $1/ $2были предоставлены, и это плохо ударило некоторых клиентов Sun при неправильном применении патча Solaris (по этой ссылке).

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

rm -rf /*
cd /tmp &&  rm -rf .*/   # on some systems where rm -rf ../ still removes
                         # the content of ../ and shells that still
                         # may include . and .. in glob expansions.
rm -rf -- "$diretcory"/* # note the misspelled variable name
dir='foo '; rm -rf $dir/*

Также удалил бы все. Известно, что завершение имени файла оболочки вызывает такие проблемы, когда вы

rm -rf someth<Tab>/*

Расширен до:

rm -rf something /*

Потому что somethingтак случилось, что это не каталог.

Оболочки, такие как tcshили zshдобавят дополнительную подсказку при попытке вызова rmс *подстановочным знаком ( tcshне по умолчанию).



1
Как молодой кооператив SA, я пытался стереть скрытые файлы в каталоге пользователя в SunOS rm -rf .*с его домашнего каталога . Вскоре после этого все телефонные линии загорелись ...
Аарон Д. Мараско

Я поставил $ rm -rf. * = Rm -rf / в запутанном виде, чтобы добраться туда.
Escoce

@GuruAdrian уверен, * означает совпадать со всеми так. * = .Filename, но также ../ и, следовательно, ../ .. и ../../ .. до бесконечности, пока вы не исчерпаете место для команды.
Escoce

возможно в современных оболочках. Так было не всегда. Я оставил эту глубину системного администрирования и разработки более 15 лет назад
Escoce
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.