Хорошо. После нескольких попыток сформулировать этот вопрос, оказывается, что он будет длинным. Anywho:
Рассмотрим следующую структуру файла:
photos/
ants/
pic1.jpg
animals/
dog.png
profile_pic.jpg
если ты это сделаешь
cd photos
ls
Вы получаете
ants/ animals/ profile_pic.jpg
Однако, поскольку каталоги «Отпуск» и «Животные» содержат только по одному файлу, возможно, было бы полезнее получить
ants/pic1.jpg ani../dog.png profile_pic.jpg
напрямую, в отличие от посещения каждого из животных и отпуска. Однако при завершении табуляции, как в cd a, вы хотели бы вместо этого предложения каталогов.
Итак, я знаю, что автодополнение bash обрабатывается скриптом /etc/bash_completion (я не хочу туда вдаваться) и библиотекой readline, но это на самом деле не влияет на ls и, конечно, не поможет, если вы хотите расширить функциональность файловых менеджеров, таких как nautilus. Поэтому я надеялся, что часть этого можно решить с помощью пользовательской файловой системы через fuse. Первоначальное исследование, основанное наэтот урокОднако это было несколько удручающе, поскольку файловая система Fuse, похоже, никак не различает мои различные варианты использования (readdir, opendir, releasedir каждый раз).
Сформулировать вопрос: Каким образом можно было бы реализовать подобную функциональность, если бы это вообще было возможно без серьезной переработки ядра? Где мне искать дополнительную информацию?
Спасибо, что уделили нам время!
EDIT: Для ясности: bash — полезный пример, но в конечном итоге я хочу, чтобы то же самое было и в nautilus, и в любой другой программе, обращающейся к файлам, и я в любом случае собираюсь написать файловую систему для решения других проблем.
решение1
Самый простой способ сделать это — написать скрипт bash, который сделает это за вас. Я почти уверен, что вы не захотите кодировать это в ядре или файловой системе :)
Такая логика должна работать:
Спуститься в каталоги... Проверить, есть ли один файл... распечатать папку/файл... в противном случае распечатать верхнюю папку
решение2
К сожалению, я не могу опубликовать комментарий, поэтому мне придется написать "ответ" (я все еще не понимаю этого решения, но хватит ругани). Поскольку вы уже отбросили этот bash
вариант и намекнули на FUSE
решение, я хотел бы дать вам пару "более или менее жизнеспособных" идей, пока вы реализуете свое mp3fs
:
Улучшение
struct stat
с новым типом, скажемst_nfiles
. Каждый раз, когда выcreate()/symlink()/hardlink()
файл, вы будете обновлять эту запись в соответствующихFUSE
операциях. Выяснение того, есть ли только одна запись в указанном каталоге, тогда будет просто поиском и сравнением с(struct stat) dirp->st_nfiles
1. Вам понадобитсяLD_PRELOAD
библиотека в вашем пользовательском пространстве, которая перехватывает и расширяет необходимыеprintf
вызовы для выводаstat
результатов с этим изменением.Неправильное использованиесуществующий
(struct stat) dirp->st_nlink
в вашемFUSE
коде операцийgetattr()
. Недостатком могут быть проблемы с инструментами, которые зависят отst_nlink
; если я правильно помню,find
это один из них. Это также требует глобальнойLD_PRELOAD
библиотеки для манипуляций с выводом.Анализ на летув
FUSE
коде операцийgetattr()
, аналогично тому, что вы бы сделали в чистом пользовательском пространстве.ЭтотФрагмент кода должен дать вам представление.
Не уверен, что это то, что вы хотели. Хотел бы я добавить это как комментарий, а не как полуответ. Может быть, вы хотите удалить тег bash
из этого вопроса, так как вы указали, что это вам не подходит, так как вы хотите, чтобы инструменты nautilus
вели себя так же.