19
Исходный код ls
доступен для просмотра онлайн на GNU Savannah . В большинстве случаев вычисляется требуемая максимальная ширина (например, с использованием mbswidth
функции для текста), а затем используются классические printf
спецификаторы формата функции C и некоторые ручные отступы. Смотрите, например, функции format_user_or_group()
и gobble_file()
.
TL; ДР: нет "магии", просто много грубых вычислений.
Если вам нужны такие аккуратные таблицы для собственного вывода, используйте column
:
$ grep -vE '^#' /etc/fstab
UUID=cdff3742-9d03-4bc1-93e3-ae50708474f2 / ext4 errors=remount-ro 0 1
/dev/mapper/lvmg-homelvm /home btrfs defaults,compress=lzo,space_cache,relatime 0 2
UUID="bb76cd0d-ae1d-4490-85da-1560c32679cd" none swap sw 0 0
UUID="a264b1b1-cf82-40aa-ab9e-a810cfba169a" /home/muru/arch btrfs defaults,compress=lzo,space_cache,relatime 0 2
$ grep -vE '^#' /etc/fstab | column -t
UUID=cdff3742-9d03-4bc1-93e3-ae50708474f2 / ext4 errors=remount-ro 0 1
/dev/mapper/lvmg-homelvm /home btrfs defaults,compress=lzo,space_cache,relatime 0 2
UUID="bb76cd0d-ae1d-4490-85da-1560c32679cd" none swap sw 0 0
UUID="a264b1b1-cf82-40aa-ab9e-a810cfba169a" /home/muru/arch btrfs defaults,compress=lzo,space_cache,relatime 0 2
findmnt --fstab
. Пакет util-linux даже поставляется с библиотекой "libsmartcols" (ранее libtt), которую он использует в findmnt, lsblk и т. Д. Для печати выровненной таблицы.findmnt
раньше, но я никогда не понимал, что это может сделать это тоже./bin/ls
входит в состав пакета (GNU)coreutils
. Вы можете найти это, запустивdpkg-query -S /bin/ls
. Как только вы узнаете имя пакета, вы можете скачать любой точный исходный код любого пакета Ubuntu, из которогоapt-get source <package_name>
В дополнение к ответу @muru , здесь есть часть исходного кода, которая рассчитывает
width
правильное обоснование вывода. :Он использует
printf ("%*lu ", width, id);
. ПРИМЕЧАНИЕ: спецификатор переменной ширины поля '*'В этом случае невозможно предсказать, какая ширина поля нам понадобится при
ls -l
выполнении, т. Е. Имена каталогов могут различаться по длине. Это означает, что сама ширина поля должна быть переменной , для которой программа будет вычислять значение .C использует звездочку в позиции спецификатора ширины поля, чтобы указать printf, что он найдет переменную, которая содержит значение ширины поля в качестве дополнительного параметра.
Например, предположим, что текущее значение ширины равно 5. Оператор:
напечатает: (обратите внимание на интервал)
источник
width
Здесьscontext_width
, вычисляютсяgooble_file
, с другой функцией я уже говорил.