Indo além do ls

By | May 22, 2015

É verdade que 99% das vezes que precisamos saber alguma coisa sobre um arquivo no Linux basta dar um ls. A saída do comando vai nos mostrar informações suficientes para fazer um bocado de coisa:

[root@localhost /]# ls -l /etc/passwd
-rw-r--r--. 1 root root 938 Sep 25 2014 /etc/passwd

Alguns você vai saber dizer o que são logo de cara:

Permissões do arquivo: (-rw-r–r–.)
Dono e grupo do arquivo: (root root)
Tamanho do arquivo: (938)
Data da última alteração: (Sep 25 2014)
Nome do arquivo: (/etc/passwd)

Mas que raios é aquele 1 lá no segundo campo? E a data? Tem certeza que significa o que você acha que significa?

Vamos tentar uma coisa:

[root@localhost etc]# ls -lha vimrc 
-rw-r--r--. 1 root root 2.0K Feb 17  2012 vimrc
[root@localhost etc]# chmod g+w vimrc 
[root@localhost etc]# ls -lha vimrc 
-rw-rw-r--. 1 root root 2.0K Feb 17  2012 vimrc

Pera! Acabei de alterar o arquivo… A data continua a mesma. E ai?

Tudo bem que o ls tem diversas opções que quando usadas em conjunto vão mostrar tudo sobre o arquivo, mas um comando mais simples para entendermos o que estamos vendo é o stat:

[root@localhost etc]# stat vimrc 
  File: `vimrc'
  Size: 1962            Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 130626      Links: 1
Access: (0664/-rw-rw-r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2012-02-17 11:17:03.000000000 -0400
Modify: 2012-02-17 11:17:03.000000000 -0400
Change: 2015-05-22 11:07:31.621985977 -0300

Ahá! Isso é interessante. O comando stat vai ter mostrar metadata a respeito do arquivo. Nome do arquivo, tamanho, blocos, dispositivo, inode, links, permissões e datas.

A primeira informação que interessa aqui é “Links”, que também é 1, assim como aquele desconhecido no comando ls. Se você já ouviu as expressões soft-links e hard-links esse número é a quantidade de hard-links nesse arquivo. Mais sobre isso em alguns instantes.

A próxima coisa a se notar é a Change date. Essa coincide com a modificação que executei agora a pouco no arquivo. Mas porque não alterou a Modify date? Simples: A Modify date é atualizada quando você altera o arquivo, enquanto a Change date é atualizada quando você altera informações a respeito – ou metadata – do arquivo!

Mas vamos falar um pouco mais de hard-links…

No Linux um mesmo arquivo pode existir em diversos lugares no sistema de arquivos. Não é uma cópia, não é um link. É realmente o mesmo arquivo. Isso é possível através de um hard-link, onde um ou mais ponteiros vão estar indicando o mesmo arquivo físico em disco.

Olha isso:

[root@localhost tmp]# echo "Alo criançada" > bozo.txt
[root@localhost tmp]# ls -l bozo.txt 
-rw-r--r--. 1 root root 15 May 22 11:26 bozo.txt
[root@localhost tmp]# ln bozo.txt vovo_mafalda.txt
[root@localhost tmp]# ls -l bozo.txt 
-rw-r--r--. 2 root root 15 May 22 11:26 bozo.txt
[root@localhost tmp]# ls -l vovo_mafalda.txt 
-rw-r--r--. 2 root root 15 May 22 11:26 vovo_mafalda.txt

Percebam que o segundo campo do comando ls mudou de 1 para 2, que já sabemos se tratar do número de hard-links. Mas vamos ver com o stat:

[root@localhost tmp]# stat bozo.txt 
  File: `bozo.txt'
  Size: 15              Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 261988      Links: 2
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-05-22 11:26:42.296971035 -0300
Modify: 2015-05-22 11:26:42.296971035 -0300
Change: 2015-05-22 11:27:04.720007315 -0300
[root@localhost tmp]# stat vovo_mafalda.txt 
  File: `vovo_mafalda.txt'
  Size: 15              Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 261988      Links: 2
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-05-22 11:26:42.296971035 -0300
Modify: 2015-05-22 11:26:42.296971035 -0300
Change: 2015-05-22 11:27:04.720007315 -0300

Observem que “Device” e “Inode” para ambos os arquivos são os mesmos!  É o mesmo arquivo. Isso é bem diferente de um soft-link (ou symlink):

[root@localhost tmp]# ln -s bozo.txt papai_papudo.txt
[root@localhost tmp]# ls -l papai_papudo.txt 
lrwxrwxrwx. 1 root root 8 May 22 11:31 papai_papudo.txt -> bozo.txt
[root@localhost tmp]# stat papai_papudo.txt 
  File: `papai_papudo.txt' -> `bozo.txt'
  Size: 8               Blocks: 0          IO Block: 4096   symbolic link
Device: fd00h/64768d    Inode: 269832      Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-05-22 11:31:07.679972343 -0300
Modify: 2015-05-22 11:31:00.384982932 -0300
Change: 2015-05-22 11:31:00.385982797 -0300

O novo arquivo é claramente um link, como fica fácil de identificar tanto pelo ls como pelo stat.

Agora, o que acontece se eu remover o arquivo original?

[root@localhost tmp]# rm bozo.txt 
rm: remove regular file `bozo.txt'? y
[root@localhost tmp]# ls -l vovo_mafalda.txt 
-rw-r--r--. 1 root root 15 May 22 11:26 vovo_mafalda.txt
[root@localhost tmp]# ls -l papai_papudo.txt 
lrwxrwxrwx. 1 root root 8 May 22 11:31 papai_papudo.txt -> bozo.txt
[root@localhost tmp]# cat vovo_mafalda.txt 
Alo criançada
[root@localhost tmp]# cat papai_papudo.txt 
cat: papai_papudo.txt: No such file or directory

O arquivo vovo_mafalda.txt continua lá, mas o número de hard-links abaixou de 2 para 1. Já o papai_papudo.txt ainda aponta para um arquivo que não existe mais e quando tentamos acessá-lo recebemos um erro.

Basicamente um arquivo vai continuar existindo no sistema enquanto o número de (hard) links for igual ou maior que 1. Uma vez removidos todos os links, o sistema de arquivos efetivamente apaga o mesmo.

Como você encontra todos os hard-links para um mesmo arquivo no seu sistema? Com o find:

[root@localhost ~]# find / -xdev -samefile /etc/passwd
/etc/passwd
/etc/abc
/root/copia_do_passwd

* Notem que eu adicionei a opção xdev, que impede que o find procure em outros filesystems, já que hard-links só podem ser criados no mesmo filesystem que o arquivo original!

Pera… E esse monte de links no meu diretório?

Que bom que você perguntou!

[root@localhost tmp]# ls -ld /etc
drwxr-xr-x. 61 root root 4096 May 22 11:04 /etc

Quer dizer que tem 61 cópias do /etc no meu sistema de arquivo?

[root@localhost ~]# find / -xdev -samefile /etc
/etc

Não, pelo jeito não.

No caso de diretórios não é possível criar hard-links para eles:

[root@localhost ~]# ln /etc /root/abc
ln: `/etc': hard link not allowed for directory

A informação com o número de hard-links na verdade aponta para o número de sub-diretórios contidos naquele diretório. Olha ai:

[root@localhost ~]# find /etc -maxdepth 1 -type d|wc -l
60

A diferença de 1 (61 vs 60) é porque o comando find não lista o “..” mas ele vai na conta de hard-links.

Então tá ai.

 

No tag for this post.