5

Играя с файловой системой, я попробовал следующее:

mkdir a
cd a
rmdir .

Что приводит к:

rmdir: failed to remove ‘.’: Invalid argument

Хорошо, мистер rmdir , позвольте мне перехитрить вас:

rmdir ../a

...Хорошо.

Какие? На этот раз ошибок нет?

Мой терминал все еще говорит, что я нахожусь в каталоге a , но ls -a ничего не перечисляет (ни . Ни ..), но ls .. и pwd прежнему работают как положено.

Я как один из тех героев мультфильмов, которые вырезали свою ветку, но все еще не упали?

Если я попробую

mkdir ../a

Он создает каталог a , но это все еще не каталог, в котором я стою (ls -a . И ls -a ../a показывают разные результаты).

Если я пытаюсь создать файл с помощью touch b он отвечает:

touch: cannot touch ‘b’: No such file or directory

Но touch . работает.

Наконец, как только я покидаю свой каталог, он исчезает, и я не могу вернуться к нему.

Редактировать: Может кто-нибудь объяснить, что здесь происходит? Есть ли название для этой ситуации? Это проблема между файловой системой и Bash, или какое-то особое жестко запрограммированное поведение в Bash?

2 ответа2

9

Это не имеет ничего общего с Bash.

Это стандартное поведение Unix, прошедшее много десятилетий назад. Это стандартное поведение ядра и ничего общего с оболочками.

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

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

Вам также следует хорошо привыкнуть к мысли, что вы можете отсоединить файл, для которого какой-то процесс имеет дескриптор открытого файла, создать новый файл с тем же именем, и они будут двумя разными файлами.

Вы просто сделали то же самое с каталогом. Вы освободили каталог и отменили связь с ним, но он продолжал существовать до тех пор, пока на него больше не ссылался дескриптор открытого файла, и он больше не был рабочим каталогом каких-либо процессов. Когда вы создали новый каталог с тем же именем, которое у вас не было связи, у вас было два разных каталога.

Обратите внимание, что SUS допускает rmdir ../a если указанный каталог является текущим каталогом любого процесса. (Это не означает, что API-интерфейсы POSIX, расположенные поверх Windows NT, могут стать лазейкой, как некоторые могут подумать. QNX, например, тоже не может выполнить вызов в этом случае.) Вы, очевидно, используете операционную систему, которая (при отсутствии таких соображений, как корневые каталоги и точки монтирования, к которым ваш вопрос не относится) выбирает другую разрешенную альтернативу, а именно: отсоединение каталога, удаление . и .. записи, и запретить делать новые записи.

дальнейшее чтение

  • "рмдир". Базовые спецификации Open Group. Стандарт IEEE 1003.1. Выпуск 7. 2013.
  • "рмдир". Справочник по библиотеке операционной системы QNX Neutrino Realtime. Поддержка разработчиков QNX.
1

В дополнение к отличному ответу JdeBP, вы можете подтвердить, что это действительно так, проверив inode рассматриваемого каталога:

$ mkdir ~/foo
$ ls -di ~/foo
16654483 /home/terdon/foo
$ cd ~/foo
$ rmdir ../foo/
$ ls -di ../foo
ls: cannot access ../foo: No such file or directory
$ mkdir ../foo
$ ls -di ../foo
16654484 ../foo

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .