Odpowiedzi:
Kod źródłowy ls
jest dostępny do przeglądania online na GNU Savannah . W większości przypadków obliczana jest wymagana maksymalna szerokość (na przykład przy użyciu mbswidth
funkcji tekstu), a następnie używane są klasyczne printf
specyfikatory formatu funkcji C i niektóre ręczne wypełnianie. Zobacz na przykład funkcje format_user_or_group()
i gobble_file()
.
TL; DR: nie ma „magii”, po prostu dużo obliczeń.
Jeśli chcesz takie porządne tabele dla własnych wyników, użyj 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
wcześniej, ale nigdy nie zdawałem sobie sprawy, że to też może zrobić.
/bin/ls
jest częścią pakietu (GNU) coreutils
. Możesz to znaleźć, uruchamiając dpkg-query -S /bin/ls
. Znając nazwę pakietu, możesz pobrać dowolny kod źródłowy pakietu Ubuntu, z którego zbudowany jest plik binarny (jest to ważne), używającapt-get source <package_name>
Oprócz odpowiedzi @muru , tutaj jest część kodu źródłowego, która oblicza width
prawidłowe uzasadnienie wyniku. :
static void
format_user_or_group (char const *name, unsigned long int id, int width)
{
size_t len;
if (name)
{
int width_gap = width - mbswidth (name, 0);
int pad = MAX (0, width_gap);
fputs (name, stdout);
len = strlen (name) + pad;
do
putchar (' ');
while (pad--);
}
else
{
printf ("%*lu ", width, id);
len = width;
}
dired_pos += len + 1;
}
To wykorzystuje printf ("%*lu ", width, id);
. UWAGA: specyfikator zmiennej szerokości pola „*”
W takim przypadku nie można przewidzieć, jak dużą szerokość pola będziemy potrzebować podczas ls -l
wykonywania, tj. Nazwy katalogów mogą mieć różną długość. Oznacza to, że sama szerokość pola musi być zmienną , dla której program obliczy wartość .
C używa gwiazdki w pozycji specyfikatora szerokości pola, aby wskazać printf, że znajdzie zmienną zawierającą wartość szerokości pola jako dodatkowy parametr.
Załóżmy na przykład, że bieżąca wartość szerokości wynosi 5. Instrukcja:
printf ("%*d%*d\n", width, 10, width, 11);
wydrukuje: (zwróć uwagę na odstępy)
10 11
width
Tu jest scontext_width
, oblicza się gooble_file
, z drugiej funkcji wspominałem.
findmnt --fstab
. Pakiet util-linux zawiera nawet bibliotekę „libsmartcols” (wcześniej libtt), której używa w findmnt, lsblk itp. Do drukowania wyrównanej tabeli.