É 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.