6

Я не уверен, относится ли следующая проблема к 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 ответа3

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 .

1

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

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/strange_dir
cd /tmp/strange_dir
ls -lai                 ← Shows normal . and .., with inode numbers.
rmdir /tmp/strange_dir
pwd                     ← Still reports /tmp/strange_dir
ls -lai                 ← Shows empty directory: Total 0
ls -ldi                 ← Shows . with the same inode number it had before,
                          but with a size of 0 and a link count of 0.
cd ..                   ← Puts you back into /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("..") завершится неудачно, оболочка вычислит то, что, по ее мнению, должен быть каталог следующего уровня, и перейдет туда абсолютно.  (Но я подозреваю, что это еще не все.)

0

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

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

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