Почему текущий каталог в команде ls определен, как связано с собой?

В книге "Изучение операционной системы UNIX", существует раздел: "3.1.8 Файла Списка", который описывает ls команда.

В абзаце на ls -l это описывает столбцы вывода этой команды.

Второй столбец ls -l команда содержит единственное число. Это число находится в книге, описанной как "Количество файлов и каталогов, связанных с этим". (связанный с файлом или каталогом, названным в последнем столбце той же строки как соответствующее число.)

Я попробовал эту команду и сравнил вывод с фактической суммой файлов и каталогов в текущем каталоге.

ls -l
drwxr-xr-x   6 azbc  staff    192 Sep  7 16:09 test

В каталоге test, У меня есть 2 подкаталога и 1 файл, и 1 скрытый файл и список текущего каталога, плюс список родительского каталога, таким образом вместе 6 файлов и каталоги.

 ls -a -F
 ./                .hidden_file.txt  dir_2/
 ../               dir_1/            file_1.sh

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

Но почему текущий каталог определяется, как связано с собой?

ls -la команда для тестового каталога дает следующий вывод. (-F опция показывает a / в случае каталога позади имени каталога, и * в случае исполняемого файла)

 ls -la -F
 total 0
 drwxr-xr-x   6 azbc  staff   192 Sep  7 16:09 ./
 drwxr-xr-x+ ?? azbc  staff    ?? Sep  7 16:06 ../
 -rw-r--r--   1 azbc  staff     0 Sep  7 16:09 .hidden_file.txt
 drwxr-xr-x   2 azbc  staff    64 Sep  7 16:06 dir_1/
 drwxr-xr-x   2 azbc  staff    64 Sep  7 16:06 dir_2/
 -rwx--x--x   1 azbc  staff     0 Sep  7 16:06 file_1.sh*

Сам файл отождествляется только с одной ссылкой. Файл связан с собой? Или это связано с каталогом, в котором это находится?

С тех пор в списке каталога сам каталог представлен в списке и поэтому логичный, чтобы считаться как ссылка.

Однако в списке самого файла существует только сам файл, представленный в списке.

 ls -la -F file_1.sh
 -rwx--x--x  1 azbc  staff  0 Sep  7 16:06 file_1.sh

Это делает логичным сказать, что файл связан с собой.

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

Это кажется не последовательным.

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

Править: в ответ на @George Udosen, на:

"Теперь, чтобы попытаться ответить на Ваш запрос в комментарии:

'Что здесь перечисляется как ссылка? Файл сам перечислен? Или каталог, который содержит перечисляемый файл?'"

Если я перечисляю каталог test :

 ls -la -F test
 ...
 drwxr-xr-x   2 azbc  staff    64 Sep  7 16:06 dir_1/
 ...
 -rwx--x--x   1 azbc  staff     0 Sep  7 16:06 file_1.sh*

это определяет каталог dir_1 с 2 ссылки!

Если я затем перечисляю тот каталог test/dir_1

 ls -la -F test/dir_1
 total 0
 drwxr-xr-x  2 azbc  staff   64 Sep  7 16:06 ./
 drwxr-xr-x  9 azbc  staff  288 Sep  7 21:37 ../

Эй, действительно!! это перечисляет 2 записи!

Файл file_1.sh* был отождествлен с 1 ссылка. Если я перечисляю файл file_1.sh

 ls -la -F test/file_1.sh
 -rwx--x--x  1 azbc  staff  0 Sep  7 16:06 test/file_1.sh*

Ho!! это перечисляет действительно 1 запись!!, а именно, file_1.sh самостоятельно! и снова отождествляет тот файл с 1 запись.

Между прочим от этого может я приходить к заключению, что каждая запись перечислила наличие 1 ссылка является файлом и не каталогом? Ho, это, кажется, не имеет место, поскольку символьные ссылки также перечислены как наличие 1 ссылка / 1 запись.

6
задан 9 September 2018 в 20:56

3 ответа

Я рекомендую считать то, Что каталоги, если все на Linux - файл? для большего всестороннего знания о структуре каталогов, истории и терминологии того, как каталоги работают и ее элементы (inode, dirent структура, и т.д.), хотя это не требуется для этого вопроса.

Что является точкой '.' и точечной точкой '..' каталоги?

Взгляд на format of directories страница руководства с 1971 выпуск руководства Unix-программиста, мы видим это . и .. уже были там:

Условно, первые две записи в каждом каталоге для"." и “.. “. Первой является запись для самого каталога.

Что касается их значения, ответ может быть найден на ответе Panos. Ken Thompson объяснил как .. появился в интервью 1989 года:

Каждый раз мы сделали каталог, условно мы помещаем его в другой каталог, названный каталогом - каталог, который был dd. Его имя было dd и что все пользовательские каталоги и на самом деле большинство других каталогов, пользователи поддерживают свои собственные системы каталогов, имело указатели назад на dd, и dd был сокращен в �dot-точку, �, и dd был для каталога каталога. Это было место назад туда, где Вы могли для получения до всех других каталогов в системе для поддержания этой миски спагетти

Естественно, . как можно предположить, обозначает d или за исключением directory. Такой каталог сам естественно совместно использует то же inode число как подлинное имя каталога. Теперь, это все еще не объясняет почему каталог . связан с собой, но у меня есть идеи пары.

0. Философия Unix:

В книге 1996 года "Внутренности UNIX: НОВЫЕ Границы" Uresh Vahalia, в Главе 8, страница 222 это указано:

Unix поддерживает thenotion текущего рабочего каталога для каждого процесса, сохраняемого как часть состояния процесса. Это позволяет пользователям обращаться к файлам своими относительными путями, которые интерпретируются относительно текущего каталога.

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

1. Технические преимущества

Основное преимущество, о котором я мог думать, состоит в том, чтобы система упростила inode поиск и таким образом информацию о метаданных. Так как каталог уже имеет запись, содержащую . с тем же inode нет никакой потребности запросить через полный путь. То же идет для программирования. Рассмотрите очень простую реализацию ls. Там я использую getcwd() функция, чтобы получить текущий рабочий путь к каталогу и затем передать его opendir(). Или я мог выбросить getcwd() и просто используйте opendir('.') непосредственно. В день старых терминалов PDP-11, где емкость памяти была в немногих килобайтах, копящих на syscall наверху, будет крайне важно.

2. Пользовательское удобство:

Рассмотрите следующий пример:

mv ../filename.txt .

В презентации Hendrik Jan Thomassen было упомянуто, что исходные команды Unix были коротки из-за старых терминальных ключей, являющихся твердым нажать, таким образом это было физическое усилие на самом деле целый день вводить команды. Если бы Вы глубоки в дерево каталогов, перепечатывание полного пути текущего рабочего каталога было бы утомительно. Конечно, mv мог быть реализован с предположением этого, когда мы делаем mv <file> мы подразумеваем место назначения как "текущий рабочий каталог". Я могу только предположить относительно почему mv <original> <new> преобладавший, возможно, из-за влияния других языков программирования дня.

3. Улучшение по MULTICS:

Примечание: Я никогда не работал над MULTICS сам, таким образом, это основано на чтении источники онлайн только

Согласно руководству MULTICS 1986 года по Путям:

Относительный путь может начаться с одного или нескольких меньше символы (" <").

> символ используется на MULTICS в качестве разделителя пути (как / на Linux). Возможно это может выглядеть сбивающим с толку. Таким образом, ./ когда ссылка на команду является возможно более четкой - мы ссылаемся на имя файла, которое расположено в текущем рабочем каталоге.

Это может быть выгодно для других команд. Известно, как создать файл на Unix/Linux: touch ./file. На MULTICS, согласно swenson.org сделан через an или add_name команда:

cd foo
r 18:03 0.041 1

an foo bar
r 18:03 0.077 3

ls foo

Directories = 1.

sma  foo
       bar

r 18:03 0.065 0

На ноте стороны существует очевидное подобие когда дело доходит до .. : навигация один каталог сделана через cwd <<.

4. Ссылка на исполняемые файлы

Если Вы запускаете скрипты на ежедневной основе, Вы знаете хорошо ./script.sh синтаксис. Почему из него просто: путем оболочка работает, то, что она ищет исполняемые файлы в PATH переменная поэтому, когда Вы обеспечиваете ./ это не должно смотреть нигде. Волшебство PATH переменная - то, что заставляет Вас использовать echo вместо /bin/echo или другие очень длинные пути. Теперь позволяет, говорят, что у Вас нет этого script.sh в Вашем пути, и это находится там в Вашем текущем рабочем каталоге. Что Вы делаете теперь? Ввести /very/long/path/to/the/executable/this/typing/gets/exhausting/on/PDP-11/finally/script.sh ? Это выбросит все понятие простоты Unix! Так возвращаясь к философии Unix, это также выравнивается с принципом изящного дизайна/простоты.

Конечно, некоторые люди хотят добавить . кому: PATH, но это - на самом деле очень плохая практика, не делайте этого.

примечание стороны: особый случай .. и . указывание на то же является inode 2 - / dir, и это имеет смысл, так как это - самая высокая точка в дереве каталогов. Конечно, .. быть ПУСТЫМ могло также работать, но это более изящно, чтобы заставить его указать на / самостоятельно.


Примечание по числу каналов и каталог Hardlinks

Как Gilles правильно указал (и сослался George Udosen), число каналов для каталога запускается с 2 ( .. для родительского каталога и .), причем вся дополнительная ссылка является подкаталогом:

# new directory has link count of 2
$ stat --format=%h .
2
# Adding subdirectories increases link count
$ mkdir subdir1
$ stat --format=%h .
3
$ mkdir subdir2
$ stat --format=%h .
4
# Adding files doesn't make difference
$ cp /etc/passwd passwd.copy
$ stat --format=%h .
4
# Count of links for root
$ stat --format=%h /
25
# Count of subdirectories, minus .
$ find / -maxdepth 1 -type d | wc -l
24

Интуитивно, ссылки каталога, являющегося подкаталогами только - имеют смысл, так как жесткие ссылки имеют то же время как исходный файл. Кроме, это не точно жесткие ссылки - жесткие ссылки создают имя файла, которое указывает на те же данные. По тому определению жесткая ссылка на каталог содержала бы те же данные, т.е. содержала бы тот же список файлов. Это привело бы к циклам в файловой системе или большом количестве файлов висячей строки, если бы все жесткие ссылки на каталог были удалены. По этой причине создание жесткой ссылки не позволяется для каталогов, и использовать формулировку Gilles от другого вопроса (который я рекомендую читать), "... [я] n факт, много файловых систем действительно имеют жесткие ссылки на каталогах, но только очень дисциплинированным способом...", и это - особые случаи . и .. каталоги.

Теперь, вопрос становится тем, что на самом деле предназначено "ссылками" в контексте каталогов? TL; DR: структура каталогов является деревом, и Ссылки здесь означают количество дочерних узлов для каждого элемента дерева (с каждым листом или каталогом без subdirs, имея только 2 ссылки). В частности, ext3 и ext4 используют HTree, и xfs использует B + дерево


Заключение

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

3
ответ дан 23 November 2019 в 07:33

Из этого превосходного ответа Жиля

Исторически первая файловая система Unix создала две записи в каждом каталоге: ., указывающая на сам каталог, и .. указывает на своего родителя. Это обеспечило простой способ обхода файловой системы, как для приложений, так и для самой ОС.

Таким образом, каждый каталог имеет счетчик ссылок 2 + n, где n - количество подкаталогов. Ссылки - это запись для этого каталога в его родительском элементе, собственная запись . каталога и запись .. в каждом подкаталоге. Например, предположим, что это содержимое поддерева с корнем в /parent, все каталоги:

/parent
/parent/dir
/parent/dir/sub1
/parent/dir/sub2
/parent/dir/sub3

Тогда dir имеет количество ссылок 5: запись dir в /parent, запись . в /parent/dir и три записи .. в каждой из /parent/dir/sub1, /parent/dir/sub2 и /parent/dir/sub3. Поскольку /parent/dir/sub1 не имеет подкаталога, его счетчик ссылок равен 2 (запись sub1 в /parent/dir и запись . в /parent/dir/sub1).

Чтобы свести к минимуму количество специальных регистров для корневого каталога, у которого нет «правильного» родителя, корневой каталог содержит запись .., указывающую на себя. Таким образом, он также имеет счетчик ссылок 2 плюс количество подкаталогов, причем 2 являются /. и /...

Более поздние файловые системы имели тенденцию отслеживать родительские каталоги в памяти и обычно не нуждаются в . и .. для существования в качестве реальных записей; Типичные современные Unix-системы рассматривают . и .. как специальные значения как часть кода файловой системы, независимого от типа файловой системы. Некоторые файловые системы все еще содержат записи . и .. или делают вид, что ничего не появляется на диске.

Большинство файловых систем по-прежнему сообщают счетчик ссылок 2 + n для каталогов, независимо от того, существуют ли записи . и .., но есть исключения, например, btrfs не делает этого.

Теперь попробуем ответить на ваш запрос в комментарии:

Что здесь указывается в виде ссылки? Сам файл указан в списке? Или каталог, в котором находится указанный файл?

Эта ссылка принадлежит файлу, а не каталогу. Позвольте мне привести пример, чтобы проиллюстрировать этот факт. Теперь, если я сделаю nano file.txt, ссылка здесь будет использована для поиска номера inode для этого файла, и inode впоследствии предоставит информацию, которая позволит программе nano изменить этот файл. Помните, что inode содержит информацию об этом файле (будь то папка, файл или блочное устройство) .

Теперь каждое имя файла должно быть связано с inode number, чтобы обычные операции выполнялись с этим файлом, так что да, эта ссылка принадлежит этому файлу, а не родительскому. Надеюсь, я правильно понял ваш вопрос и тоже ответил на него.

3
ответ дан 23 November 2019 в 07:33

Ваш вопрос нечеток мне, но я пытаюсь объяснить, как вещи работают так, он мог бы помочь Вам понять это.

Каждый файл, хранивший в системе, имеет число (inode число), давайте проверим его:

$ ls -i -1 -a test/
9186865 .
9175041 ..

Я использовал -1 показать список файлов в отдельном столбце и -iдля показа inodes и -a показать скрытые файлы.

Каждый inode хранит информацию о файлах, вещах как полномочия, владелец, размер, количество ссылок, время изменения, указатели на фактические данные файлов (но не название файла).

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

Таким образом, когда я удаляю файл (также известный как удаление связи с файлом), я удаляю его ссылку из его родительского каталога, но натюрморты данных на диске.

То, когда Вы создаете новый каталог по умолчанию, он содержит 2 жестких ссылки, означает, что каждый каталог по умолчанию имеет . и .. в его списке.

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

$ mkdir test
$ ls -i -d test
9186865 drwxrwxr-x 2 ravexina ravexina 4096 Sep  7 19:37 test

Поскольку Вы видите, что количество ссылок равняется двум, теперь не имеет значения, сколько файла я создаю в этом каталоге, количество ссылок остается таким же, если я не начинаю создавать каталоги. для каждого каталога число будет увеличено 1, и теперь Вы знаете почему! потому что каждый новый каталог содержит жесткую ссылку на своего родителя: ..:

Помните то, что я сказал о каталогах?

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

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

3
ответ дан 23 November 2019 в 07:33

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

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