Réponses:
Le code source de ls
est disponible pour la navigation en ligne sur GNU Savannah . Dans la plupart des cas, la largeur maximale requise est calculée (par exemple, en utilisant la mbswidth
fonction pour le texte), puis utilise les printf
spécificateurs de format de fonction C classiques et un remplissage manuel. Voir, par exemple, les fonctions format_user_or_group()
et gobble_file()
.
TL; DR: il n'y a pas de "magie", juste beaucoup de calculs de grognement.
Si vous voulez de telles tables soignées pour votre propre sortie, utilisez 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
, mais je n'avais jamais réalisé que ça pouvait faire ça aussi.
/bin/ls
fait partie du paquet (GNU) coreutils
. Vous pouvez le trouver en exécutant dpkg-query -S /bin/ls
. Une fois que vous connaissez le nom du package, vous pouvez télécharger tout code source exact du package Ubuntu à partir duquel le binaire est construit (c'est important) en utilisantapt-get source <package_name>
En plus de la réponse de @muru , voici la partie du code source qui calcule la width
bonne justification de la sortie. :
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;
}
Il utilise printf ("%*lu ", width, id);
. REMARQUE: spécificateur de largeur de champ variable '*'
Dans ce cas, il n'est pas possible de prédire la largeur d'une zone dont nous aurons besoin lors de l' ls -l
exécution, c'est-à-dire que les noms des répertoires peuvent varier en longueur. Cela implique que la largeur du champ lui-même doit être une variable , pour laquelle le programme calculera une valeur .
C utilise un astérisque à la position du spécificateur de largeur de champ pour indiquer à printf qu'il trouvera la variable qui contient la valeur de la largeur de champ comme paramètre supplémentaire.
Par exemple, supposons que la valeur actuelle de largeur est 5. L'instruction:
printf ("%*d%*d\n", width, 10, width, 11);
imprimera: (notez l'espacement)
10 11
width
ici est scontext_width
, calculé par gooble_file
, l' autre fonction que j'ai mentionnée.
findmnt --fstab
. Le paquet util-linux est même livré avec une bibliothèque "libsmartcols" (anciennement libtt) qu'il utilise dans findmnt, lsblk, etc. pour imprimer une table alignée.