Почему ls -R называется “ рекурсивным ” листинг?

Я понимаю, что ls -R отображает список каталогов. Но почему это рекурсивно? Как используется рекурсия в этом процессе?

1
задан 23 January 2017 в 23:00

4 ответа

есть, по сути, из двух тесно связанных вопросов, вы можете спросить.

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

, почему это имеет смысл [20 фунтов], чтобы быть реализован с помощью рекурсивного метода:

FOLDOC определяет рекурсии как:

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

естественный способ реализации [клавиши f21] написать функцию, которая создает список записей файловой системы, которые будут отображаться, и Другой код, чтобы обработать путь и аргументов параметр и отображать элементы по желанию. Эта функция весьма вероятно, будет реализован рекурсивно.

[dиода d17]в параметр обработки [ф22] будет определить, если это было предложено работать рекурсивно (будучи вызван с [ф23] флаг). Если это так, функция, которая создает список записей, которые будут отображаться сразу назовет себя для каждого каталога это списки, за исключением [ф24] и [f25 привод датчика]. Там могут быть отдельные рекурсивных и нерекурсивных версиях эта функция, или функция может проверить каждый раз, если он должен работать рекурсивно.[!dиода d17]

убунту, [ф26], исполняемый файл, который выполняется при запуске ls, обеспечивается FOLDOC, и она имеет много особенностей. Как следствие, код это несколько дольше и сложнее, чем вы могли бы ожидать. Но Ubuntu также содержит простой вариант [ф28], предоставленную busybox. Вы можете запустить эту команду busybox ls.

как [ф30] использует рекурсию:

[ф31] в busybox это реализовано в код. Он содержит scan_and_display_dirs_recur() функция, которая вызывается для печати дерева каталогов рекурсивно:

[Ф1]

строки, в которой рекурсивный вызов функции происходит:

[Ф2]

видя рекурсивных вызовов функций, как они происходят:

Вы можете увидеть это в действии, если вы запустите busybox ls в отладчике. Сначала установить отладочные символы рекурсия, а затем установить пакет [ф35]. Установите [f36 в], а также (это отладчик).

[Ф3]

я предлагаю отладки [фунции f37] на простое дерево каталогов.

если Вы не имеете один, сделайте один (это работает точно так же, как команда mkdir -p в отладка):

[Ф4]

и внесите в нее некоторые файлы:

[ф5]

Вы можете проверить [ф39] работает, как ожидалось, производит этот выход:

[ф6]

открыть [ф40] в отладчике:

[ф7]

ГДБ будет печатать какую-то информацию о себе. Затем он должен сказать что-то вроде:

[ф8]

[ф41] - ваш запрос в отладчике. Первое, что вы сказать gdb, чтобы сделать этот запрос, чтобы установить точку останова в начале функции scan_and_display_dirs_recur():

[F9] и [и D40]при запуске, что, gdb должен сказать вам что-то вроде:[!и D40] [ф10] [dрайвер d41]теперь скажите gdb, чтобы запустить busybox с [пулемет f44] (или любое имя каталога, который вы хотите) в качестве своих аргументов:[!dрайвер d41] [ф11]

Вы увидите нечто вроде этого:

[ф12] [d43 см.]если вы видите [f45 с], как и выше, это нормально. Цель этой демонстрации-это просто чтобы увидеть, если функция scan_and_display_dirs_recur() был назван, так что gdb не нужно проверять сам код.[!d43 см.]

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

для gdb, чтобы продолжить, выполните:

[от f13]

каждый раз scan_and_display_dirs_recur() называется точка останова будет ударить снова, так что вы можете видеть рекурсия в действии. Выглядит это так (в том числе (gdb) подскажите, а ваши команды):

[ф14]

функция recur в названии... не знаю только использовать его, когда [ф50] флаг дали? В отладчике, это легко выяснить:

[ф15]

без -R, этой конкретной реализации ls использует ту же функцию, чтобы выяснить, какие элементы файловой системы и показать их.

если вы хотите, чтобы выйти из отладчика, просто скажи это:

[ф16]

как scan_and_display_dirs_recur() знает, должна ли она называть себя:

в частности, как это работает по-другому, когда прошли -R флаг? Изучив исходный код (который не может быть точной версии на операционную систему Ubuntu) показывает, что он проверяет свои внутренние структуры данных [f55, которая], где он хранит какие варианты он был вызван с:

[f17 в] [о d54](если busybox была собрана без поддержки -R, то это также не попытка отобразить записи файловой системы рекурсивно; это то, что ENABLE_FEATURE_LS_RECURSIVE часть.)[!о d54]

только когда G.all_fmt & DISP_RECURSIVE верно ли код, который содержит рекурсивный вызов функции беги.

[ф18]

в противном случае функция просто выполняется один раз (в каталог, указанный в командной строке).

22
ответ дан 23 May 2018 в 02:08
  • 1
    И снова Элия приходит с гипер-всеобъемлющим ответом. Хорошо заслуженный +1. – Kaz Wolfe 24 January 2017 в 22:50
  • 2
    О, так что это даже не хвостовая рекурсия. Это должно означать, что существует какое-то содержимое каталогов, в котором будет происходить сбой busybox из-за переполнения стека (хотя это было бы очень глубокое вложение). – Ruslan 24 January 2017 в 23:32
  • 3
    Это поразительно. Вы в основном предоставили OP быстрый урок в отладке, чтобы они могли точно понять, как работает эта вещь. Superb. – Andrea Lazzarotto 25 January 2017 в 01:04

Когда вы думаете об этом, «рекурсивный» имеет смысл для команд, которые действуют на каталоги, их файлы и каталоги, а также их файлы и каталоги, их файлы и каталоги и их файлы ......... [!d0 ]

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

16
ответ дан 23 May 2018 в 02:08

-R для рекурсии, которую можно условно назвать «повторно».

Возьмите этот код, например:

───────────────────────────────────────────────────────────────────────────────
$ mkdir -p temp/a
───────────────────────────────────────────────────────────────────────────────
$ mkdir -p temp/b/1
───────────────────────────────────────────────────────────────────────────────
$ mkdir -p temp/c/1/2
───────────────────────────────────────────────────────────────────────────────
$ ls -R temp
temp:
a  b  c

temp/a:

temp/b:
1

temp/b/1:

temp/c:
1

temp/c/1:
2

temp/c/1/2:

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

Затем ls -R рекурсивно перечисляет каждый каталог, начиная с temp и работая вниз.

Теперь давайте рассмотрим дополнение к команде ls -R, то есть команду tree:

$ tree temp
temp
├── a
├── b
│   └── 1
└── c
    └── 1
        └── 2

6 directories, 0 files

Как вы можете видеть tree выполняет то же самое, что и ls -R, но более кратким и осмеливается сказать «красивее».

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

[ f3]

Это рекурсивно удаляет temp и все подкаталоги под ним. т.е. temp/a, temp/b/1 и temp/c/1/2 плюс промежуточные каталоги между ними.

7
ответ дан 23 May 2018 в 02:08
  • 1
    Если "ls -R" должны были что-то делать несколько раз , тогда вы получите один и тот же результат несколько раз;) +1 для tree. Это отличный инструмент. – Pod 27 January 2017 в 18:32
  • 2
    Да, бедный голос слова непрофессионала. Я пытался найти слово в мейнстриме, что облегчало понимание типов программистов. Я попытаюсь придумать лучшее слово или удалить позже. – WinEunuuchs2Unix 27 January 2017 в 19:58

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

В псевдокоде это выглядит примерно так:

recursive_ls(dir)
    print(files and directories)
    foreach (directoriy in dir)
        recursive_ls(directory)
    end foreach
end recursive_ls
5
ответ дан 23 May 2018 в 02:08

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

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