Respostas:
O código fonte do ls
está disponível para navegação online no GNU Savannah . Na maioria dos casos, a largura máxima exigida é calculada (por exemplo, usando a mbswidth
função para texto) e, em seguida, usa os printf
especificadores de formato de função C clássicos e algum preenchimento manual. Veja, por exemplo, as funções format_user_or_group()
e gobble_file()
.
TL; DR: não há "mágica", apenas muita computação grunhida.
Se você deseja tabelas limpas para sua própria saída, use 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
antes, mas nunca percebi que isso também poderia ser feito.
/bin/ls
faz parte do pacote (GNU) coreutils
. Você pode encontrar isso executando dpkg-query -S /bin/ls
. Depois de saber o nome do pacote, você pode baixar qualquer código fonte exata de pacotes do Ubuntu a partir do qual o binário é construído (isso é importante) usandoapt-get source <package_name>
Além da resposta do @muru , aqui está a parte do código fonte que calcula width
a justificação correta da saída. :
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;
}
Ele usa printf ("%*lu ", width, id);
,. NOTA: especificador de largura de campo variável '*'
Nesse caso, não é possível prever o tamanho de uma largura de campo que precisaremos quando ls -l
for executada, ou seja, os nomes dos diretórios podem variar em tamanho. Isso implica que a própria largura do campo precisa ser uma variável , para a qual o programa calculará um valor .
C usa um asterisco na posição do especificador de largura do campo para indicar a printf que encontrará a variável que contém o valor da largura do campo como um parâmetro adicional.
Por exemplo, suponha que o valor atual da largura seja 5. A instrução:
printf ("%*d%*d\n", width, 10, width, 11);
irá imprimir: (observe o espaçamento)
10 11
width
aqui é scontext_width
, calculado por gooble_file
, a outra função que mencionei.
findmnt --fstab
. O pacote util-linux ainda vem com uma biblioteca "libsmartcols" (anteriormente libtt), que ele usa em findmnt, lsblk, etc. para imprimir uma tabela alinhada.