'Комната*' когда-нибудь удаляет родительский каталог?

Существует умный взлом, упомянул здесь что использование GDB для присоединения к процессу и названной утилите dupx оборачивает эту функциональность.

От dupx страница справочника:

Dupx является простой утилитой для переотображения файлов уже запускающей программы. Оболочки как Bash позволяют легкое входной/вывод/ошибку перенаправление в то время, когда программа запущена с помощью >, < - как синтаксис, например: echo 'redirect this text' > /tmp/stdout перенаправит вывод echo кому: /tmp/stdout.

Стандартные оболочки однако не обеспечивают возможность переотображения (перенаправления) вывода (или вводят, или ошибка) для уже запущенного процесса. Dupx пытается решить эту проблему при помощи dup(2) системный вызов изнутри gdb(1). Dupx в настоящее время реализуется как простая обертка оболочки вокруг a gdb сценарий.

53
30.01.2014, 18:14
1 ответ

Последнее (по состоянию на 2017) версия спецификации POSIX для rm утилита здесь (и предыдущая там) и запрещает удаление . и ...

Если или точки файлов или точечной точки будут указаны как часть базового имени операнда (то есть, заключительный компонент пути) или если операнд решит к корневому каталогу, то комната должна записать сообщение диагностики в стандартную погрешность и не сделать ничего больше с такими операндами.

Как отмечено @jlliagre, частью о / дополнение в SUSv4.

Самая старая общедоступная спецификация Unix, которую я мог найти (CAE rev2 за 4 XPF (1994)), уже указала это . и .. не может быть удален, хотя комментарии в GNU fileutils журнал изменений предполагают, что он уже имел место в более старых спецификациях POSIX.

Обратите внимание, что это относится dir/.. и ../ также, но некоторые реализации (включая сертифицированные UNIX как Солярис 11 и macOS) все еще не охраняют против rm -rf ../ или rm -rf .*/).

история

Ранние нельды

-r опция к rm был добавлен в Unix V3 (1973), хотя он только удалял содержание каталогов, необходимо будет все еще использовать rmdir удалить каталоги.

Это изменилось в Unix V7 (1979, выпуск, который также представил Оболочку Bourne и из которого большинство Нельдов происходит). rm -r теперь удаленные каталоги также и не удалили бы .. дерево каталогов. Состояния страницы справочника:

Запрещается удалить файл .. просто избегать антиобщественных последствий непреднамеренного выполнения чего-то как rm -r .*.

(хотя можно было бы обсудить это rm -r .* является все еще антиобщественным, поскольку это удаляет все потому что . включен).

Это все еще принимало для удаления . хотя это не удалило бы связь . или .. записи. Таким образом, rm -r . эффективный путь состоял в том, чтобы освободить текущий каталог.

Также обратите внимание, что гарантия была только для литерала .. аргумент, не для dir/.. или ./... Так, rm -rf ./.* все еще удалил бы все в родительском каталоге рекурсивно.

Интересно видеть, что это уже было к обходному решению ошибкой/ошибкой, которой шарики могли включать . и .. в их расширении. Это было зафиксировано в оболочке Forsyth (основание для исходной оболочки Minix и pdksh) в конце 80-х, zsh (1990) и fish (2005) но не другие оболочки и в особенности не POSIX sh язык, который требует расширения .* включать . и .. если они возвращаются readdir() (bash решает проблему частично только с shopt -s dotglob где шарики (кроме .xxx ), не включают . или .., и с ksh, можно зафиксировать его путем выполнения FIGNORE='@(.|..)').

При точном запрещении . также был добавлен, не всегда ясно и меняется в зависимости от каждого Unix. Несколько результатов ниже.

BSDs

Запрещение . был добавлен когда-то между 2.9BSD (1983) и 2.10BSD (1987) и между 4.2BSD (1983) и 4.3BSD (1986) (см., что это изменение добавило метку времени к 1985 в unix-history-repo).

$ 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 (Сеть/1 BSD 4.3).

На эту дату, rm из FreeBSD (и производные как macOS) все еще освобождает текущий или родительский каталог на rm -rf ./ или rm -rf ../ хотя (имеет значение для rm -rf .*/).

System V

У меня нет большой информации, поскольку никакой источник или двоичный файл не общедоступны для производных Unix AT&T после V7. В его руководстве онлайн HPUX (на основе Системы III) все еще упоминает, что это только запрещает .. в то время как эффективно это запрещает обоим, который является признаком, что, вероятно, по крайней мере, SysIII не запретил удаление . (редактирование: Теперь рассмотрение SysIII rm исходный код, это фактически неизменно начиная с Unix V7).

Все другие руководства онлайн я проверил удаление упоминания . или .. запрещается, который, как должны ожидать, будет совместимым POSIX.

Солярис rm все еще освобождает текущий или родительский каталог на rm -rf ./ или rm -rf ../.

GNU

Ранний журнал изменений для GNU fileutils имеет всю историческую информацию.

В то время как первоначально никакое удаление . или .. были запрещены, .. был запрещен сначала и затем оба (включая dir/.), все между 1990 и 1991.

другое

Поскольку мы видели, в zsh, расширение .* (или любой шарик), никогда не включает . или .. (даже в sh режим эмуляции). rm встроенный (который Вы получаете если Вы zmodload zsh/files) поэтому не рассматривает . или .. особенно. Так, с этим zsh встроенный, Вы можете rm -rf . или rm -rf .. опустеть . или .., но rm -rf .* не удалит . или ...

В busybox rm, запрещение удаления . и .. был добавлен в 0,52 (2001)

59
27.01.2020, 19:33
  • 1
    Нечетный, который, кажется, указывает это rm -rf . / (отметьте пространство), должен распечатать два предупреждения (для . и /) и выход, но мы, кажется, получаем вопрос, спрашивающий, как восстановить с той каждой пары месяцы. –  Kevin 10.09.2013, 19:00
  • 2
    @Kevin Не всеми системами является совместимый POSIX, и ограничение корневого каталога было только явно добавлено в последнем выпуске POSIX. –  jlliagre 10.09.2013, 19:15
  • 3
    @jlliagre я вижу. GNU обычно пытается реализовать POSIX (+extensions, конечно), и я предположил бы, что они захотят вставить этого, но если бы это является довольно новым, который объяснил бы это. –  Kevin 10.09.2013, 19:23
  • 4
    @Stephane обновлений: Вы правы, но я все еще добавил бы большое "да, Это могло произойти! Но..." в начале Вашего ответа, так, чтобы люди, несомненно, знали, что действительно, на некоторых (более старый или просто совместимый неPOSIX) системы, могли удалить родительские каталоги. Я пытаюсь всегда указать на них возможность (т.е., я пытаюсь остаться на безопасной стороне, даже если она сделает ответ иногда тяжелее для читения/помнившего), то ^^ –  Olivier Dulac 10.09.2013, 20:49
  • 5
    @MartinSchröder, На BSDs, это было добавлено где-нибудь между 2.8BSD и 2.10BSD (прежде чем только ".." как запретили в UnixV7), и между 3BSD и 4.3RENO. В системах SysV это менее ясно. Руководство HPUX, например, утверждает, что только запрещает ".." но в действительности это запрещает обоим "." и "..", это - только руководство, которое не актуально. –  Stéphane Chazelas 11.09.2013, 15:19

Теги

Похожие вопросы