Linux: Как создать каталог без "." а также ".."?

Я не уверен, относится ли следующая проблема к busybox: у меня установлено встроенное устройство с busybox. Из того, что я понимаю, когда создается каталог, обычно автоматически создаются 2 скрытых файла: . представлять текущий каталог и .. представлять родительский каталог. Например, набрав mkdir -p /tmp/normal_dir; cd /tmp/normal_dir; ls -a, вывод будет . ..,

Тем не менее, я видел случай, когда существующий каталог (/tmp/strange_dir) не показывает . а также .., То есть набрав cd /tmp/strange_dir; ls -a, вывод пуст, хотя навигация к родительскому каталогу все еще работает. То есть набрав cd .., содержание правильное.

Мой вопрос: как мог такой каталог без . а также .. (лайк /tmp/strange_dir) быть созданным? Я озадачен.

3 ответа

Это может произойти, если вы обращаетесь к каталогу по символической ссылке, но связанный каталог удаляется. Например, в /tmp Давайте создадим каталог и символическую ссылку на этот каталог:

$ cd /tmp
$ mkdir normal_dir
$ ln -s normal_dir strange_dir

Теперь, если мы перейдем к strange_dir, мы получаем ожидаемый результат:

$ cd strange_dir
$ ls -a
. ..

Если, однако, мы удаляем каталог normal_dir не меняя каталог, действительно мы получаем интересный результат:

$ rmdir /tmp/normal_dir
$ ls -a

$ ls -al
total 0

Поэтому, хотя наша ссылка теперь ни на что не указывает, рабочий "каталог" оболочки остается прежним:

$ pwd
/tmp/strange_dir

$ cd /tmp/strange_dir
bash: cd: /tmp/strange_dir: No such file or directory

$ ls -al
total 0

Бег stat -L . в то время как наш рабочий каталог все еще находится в /tmp/strange_dir сейчас покажу Size: 0 как обсуждено в вышеупомянутых комментариях. Хотя на выходе ls сейчас ничего не показывает (даже не . ни ..), мы все еще можем нормально переходить в родительский каталог .. в этом случае, как вы обрисовали в общих чертах:

$ cd ..
$ pwd
/tmp

$ ls -a
. .. strange_dir

Хотя символическая ссылка все еще существует, она ни на что не указывает, поэтому мы не можем cd Вернуться в strange_dir на данный момент, если каталог /tmp/normal_dir воссоздан. Чтобы очистить, мы можем просто удалить символическую ссылку, вызвав rm /tmp/strange_dir,

Вполне возможно, что такая аберрация может быть создана, если кто-то сказал

mkdir /tmp/strange_dir

в то время, когда файловая система была заполнена (т. е. свободных блоков не было). Было бы (возможно) еще возможно создать strange_dir запись в каталоге /tmp потому что для этого потребуется только несколько байтов неиспользуемого пространства в одном из блоков, уже выделенных для /tmp, Но было бы невозможно выделить блок для strange_dir сам, и поэтому было бы невозможно создать . а также .. записей. В таком случае я бы ожидал mkdir программа для удаления (отмены связи) strange_dir запись в каталоге /tmp, но программное обеспечение не всегда делает то, что я ожидаю.

Другие возможности:

  • mkdir был прерван (прекращен) между созданием strange_dir запись в каталоге /tmp и создание . а также .. записи в strange_dir, Я бы ожидал mkdir поймать сигнал прерывания (то есть Ctrl + C) и очистить после себя, но смотри выше относительно программного обеспечения и моих ожиданий от него. И, конечно, он не может поймать сигнал уничтожения или сбой системы.
  • rmdir был прерван между . а также .. записи в strange_dir и отменяя связь strange_dir запись в каталоге /tmp,

Можно ожидать, что fsck который запускается после аварии, обнаружит strange_dir и что-то с этим делать, но....

Да, конечно, если каталог имеет размер 0, это означает, что у него нет выделенных ему блоков, и, следовательно, он не может иметь никакого содержимого (даже маленьких, таких как . а также ..).

Я не до конца понимаю почему cd .. будет работать, когда нет .., но смотрите обсуждение в разделе Удаление каталога изнутри с использованием интерфейса командной строки. Оказывается, что

 mkdir / tmp /ird_dir
CD / TMP / странный_дир
ls -lai ← Показывает нормально. и.. , с номерами инодов.
rmdir / tmp /ird_dir
pwd ← Все еще сообщает / tmp / strange_dir
ls -lai ← Показывает пустой каталог: всего 0
ls -ldi ← Показывает. с тем же номером инода, что и раньше, 
                           но с размером 0 и количеством ссылок 0.
cd.. ← Возвращает вас обратно в / tmp 

Эта ситуация не совсем аналогична ситуации в этом вопросе, потому что в другом случае strange_dir удаляется из /tmp, Но это говорит о том, что cd .. является особенным, и иногда работает, когда нет очевидного механизма, с помощью которого он мог бы.

Странное различие между pwd и / bin / pwd предполагает возможность того, как это может работать. Оболочка отслеживает ваш текущий каталог. То есть он отслеживает лучшее предположение о том, какой у вас текущий каталог. Это может быть одурачено символическими ссылками и трюками, такими как

mkdir /tmp/foo
cd /tmp/foo
mv /tmp/foo /tmp/foobar

т.е. он все еще будет думать, что текущий каталог /tmp/foo и вот что pwd сообщу, но pwd -P а также /bin/pwd сообщит /tmp/foobar, Так что, может быть, если chdir("..") терпит неудачу, оболочка вычисляет то, что, как она думает, должна быть ваша директория следующего уровня, и отправляется туда абсолютно. (Но я подозреваю, что это еще не все.)

Спасибо за обсуждения до сих пор. Ниже приводится объяснение моего коллеги, который не является членом сообщества суперпользователей:

/tmp/strange_dir в моем случае это каталог NBD/VFS (сетевое блочное устройство / виртуальная файловая система). Этот тип виртуальной файловой системы отличается от более традиционных файловых систем и имеет собственную реализацию команд оболочки. Поэтому неудивительно, что когда каталог пуст, ls -a показывает только cd .. позволяет перейти в родительский каталог.

Другие вопросы по тегам