Estou criando um script de shell que pegaria um nome de arquivo / caminho para um arquivo e determinaria se o arquivo é um link simbólico ou um link físico.
A única coisa é que eu não sei como ver se eles são um link físico. Criei 2 arquivos, um link físico e outro simbólico, para usar como arquivo de teste. Mas como eu determinaria se um arquivo é um link físico ou simbólico em um script de shell?
Além disso, como eu encontraria a partição de destino de um link simbólico? Então, digamos que eu tenha um arquivo vinculado a uma partição diferente, como eu encontraria o caminho para esse arquivo original?
shell-script
files
symlink
hard-link
k-Rocker
fonte
fonte
ln /foo/bar/ /foo/bar2
faz um hardlink enquantoln -s /foo/bar /foo/bar2
faz um link simbólico, é isso que ele quer dizer?bar2
ebar
são ambos os links físicos, apenas apontando para o mesmo inode.bar
ebar2
são igualmente importantes. Um não é um link para o outro, ambos são links, mas apontam para o mesmo inode.ln
não são diferentes dos arquivos regulares.Respostas:
A resposta de Jim explica como testar um link simbólico: usando
test
o-L
teste de.Mas testar um "link físico" não é, estritamente falando, o que você deseja. Os links físicos funcionam devido à maneira como o Unix lida com arquivos: cada arquivo é representado por um único inode. Então, um único inode possui zero ou mais nomes ou entradas de diretório ou, tecnicamente, links físicos (o que você está chamando de "arquivo").
Felizmente, o
stat
comando, quando disponível, pode dizer quantos nomes um inode possui.Então, você está procurando algo parecido com este (assumindo aqui a implementação GNU ou busybox
stat
):O
-c '%h'
bit informastat
apenas para gerar o número de hardlinks para o inode, ou seja, o número de nomes que o arquivo possui.-gt 1
depois verifica se é mais que 1.Observe que links simbólicos, como qualquer outro arquivo, também podem ser vinculados a vários diretórios, para que você possa ter vários links físicos para um link simbólico.
fonte
stat -f %l /path/to/file
. Você também pode usargstat -c %h /path/to/file
se tiver o coreutils GNU instalado sem os nomes padrão (com Homebrew no OS X).Um exemplo:
As entradas
f1
,f2
ef3
diretório são o mesmo arquivo (mesmo inode: 10802124, você notará que o número de links é 3). Eles são links físicos para o mesmo arquivo regular .s4
es5
também são o mesmo arquivo (10802384). Eles são do tipo link simbólico , não regulares . Eles apontam para um caminho aquis3
. Comos4
es5
são entradas do mesmo diretório, esse caminho relativos3
aponta para o mesmo arquivo (aquele com inod 10802347) para ambos.Se você fizer um
ls -Ll
, está pedindo para obter informações sobre o arquivo após resolver os links simbólicos:Você descobrirá que todos eles resolvem o mesmo arquivo (10802124).
Você pode verificar se um arquivo é um link simbólico
[ -L file ]
. Da mesma forma, você pode testar se um arquivo é regular[ -f file ]
, mas, nesse caso, a verificação é feita após a resolução dos links simbólicos.hardlinks não são um tipo de arquivo, são apenas nomes diferentes para um arquivo (de qualquer tipo).
fonte
Usando os operadores
-h
e-L
dotest
comando:http://www.mkssoftware.com/docs/man1/test.1.asp
De acordo com esse encadeamento SO , eles têm o mesmo comportamento, mas
-L
é preferido.fonte
inode
. Além disso, os links flexíveis mostram uml
no início de suals -l
saída ... Eu acho que você pode juntar essas regras em um script, além do[[ -L file ]]
teste para ver se o arquivo fornecido é flexível ou rígido .Há muitas respostas corretas aqui, mas não acho que alguém realmente tenha abordado a percepção equivocada original. A pergunta original é basicamente "quando eu faço um link simbólico, é fácil identificá-lo depois. Mas não consigo descobrir como identificar um link físico". E sim, as respostas basicamente se resumem a "você não pode" e mais ou menos explicam o porquê, mas ninguém parece ter reconhecido que, na verdade, é confuso e estranho.
Se você está lendo tudo isso e descobriu o que está acontecendo, é bom; você não precisa ler meu pedacinho. Se você ainda está confuso, continue.
A resposta realmente muito curta é que um link físico não é realmente um link, não da maneira que um link simbólico é. É uma nova entrada na estrutura de diretórios que aponta para o mesmo grupo de bytes que a entrada do diretório original e, depois que você a criou, é tão 'real' e legítima quanto a primeira. Todo arquivo 'normal' na sua unidade possui pelo menos um link físico; sem isso, você não veria isso de forma algumadiretório e não conseguiria se referir a ele ou usá-lo. Portanto, se você possui um arquivo Fred.txt e vincula Wilma.txt e Barney.txt a ele, todos os três nomes (e entradas de diretório) se referem ao mesmo arquivo e todos são igualmente válidos. Não há como o sistema operacional dizer que uma das entradas foi criada quando você clicou em "salvar" no seu editor de texto e as outras foram feitas com o comando "ln".
O sistema operacional não tem que manter o controle de quantas entradas diferentes estão apontando para o mesmo arquivo, no entanto. Se você excluir o Wilma.txt, não é surpresa que você não libere espaço na sua unidade. Mas se você excluir Fred.txt (o arquivo 'original'), ainda não liberará espaço em sua unidade, porque os dados na unidade conhecidos como Fred.txt também serão Barney.txt. Somente quando você exclui todas as entradas do diretório o SO desaloca o espaço que os dados estavam ocupando.
Se o Barney.txt fosse um link simbólico, a exclusão do Fred.txt teria desalocado o espaço e o Barney.txt agora seria um link quebrado. Além disso, se você mover ou renomear um arquivo que possui um link simbólico apontando para ele, quebrará o link. Mas você pode mover ou renomear um arquivo com link físico o quanto quiser, sem interromper as outras entradas de diretório que apontam para esse arquivo / dados, porque todas elas são entradas de diretório que se referem ao mesmo bloco de dados na unidade (usando o inode # desses dados).
[Dois anos depois, e essa última parte me confundiu por um minuto, então acho que vou esclarecer. Se você digitar "mv ./Wilma.txt ../elsewhere/Betty.txt", parece que você está movendo o arquivo, mas, na verdade, não está. O que você realmente está fazendo é remover um item de linha da lista de diretórios do diretório atual, aquele que diz "o nome 'Wilma.txt' está associado aos dados que podem ser encontrados usando o inode ###### #, "e adicionando um novo item de linha à lista de diretórios ../elsewhere que diz" o nome 'Betty.txt' está associado aos dados que podem ser encontrados através do inode ####### ". É por isso que você pode 'mover' um arquivo de 2 gigabytes tão rapidamente quanto um arquivo de 2 kilobytes, desde que você os esteja movendo para outro local na mesma unidade.]
Como o sistema operacional precisa acompanhar quantas entradas de diretório diferentes estão apontando para a mesma porção de dados, é possível saber se um arquivo específico foi vinculado por hardware, mesmo que você não tenha certeza se a entrada de diretório que você está olhando é o 'original' ou não. Uma maneira é o comando "ls", especificamente "ls -l" (é um L minúsculo após o traço)
Para emprestar um exemplo anterior ....
A primeira letra é um traço, por isso não é um diretório ou outra coisa exótica, é um arquivo comum 'regular'. Mas se fosse realmente comum, esse número após a parte rwx-ish seria "1", como em "há uma entrada de diretório apontando para esse bloco de dados". Mas isso faz parte de uma demonstração de links físicos, então diz "3".
Observe que isso pode levar a um comportamento estranho e misterioso (se você não tiver envolvido a cabeça em links físicos, isso é). Se você abrir o Fred.txt no seu editor de texto e fizer algumas alterações, verá as mesmas alterações no Wilma.txt e no Barney.txt? Talvez. Provavelmente. Se o seu editor de texto salvar as alterações, abrindo o arquivo original e escrevendo as alterações, sim, todos os três nomes ainda estarão apontando para o mesmo texto (recém-alterado). Mas se o seu editor de texto cria um novo arquivo (Fred-new-temp.txt), grava a versão alterada nele, exclui Fred.txt e renomeia Fred-new-temp.txt para Fred.txt, Wilma e Barney irão ainda está apontando para a versão original, não para a nova versão alterada. Se você não entender os links físicos, isso pode deixá-lo um pouco louco. :) [Ok, na verdade eu não conheço pessoalmente nenhumeditores de texto que executariam a coisa de novo arquivo / renomeação, mas eu conheço muitos outros programas que fazem exatamente isso, portanto, fique alerta.]
Uma observação final: uma das coisas que o 'fsck' (verificação do sistema de arquivos) verifica é se há blocos de dados em sua unidade que de alguma forma não são mais referenciados por nenhuma entrada de diretório. Às vezes, algo dá errado, e a única entrada de diretório que aponta para um inode é excluída, mas o espaço da unidade em si não é marcado como "disponível". Portanto, uma das tarefas do fsck é combinar todo o espaço alocado com todas as entradas do diretório para garantir que não haja arquivos não referenciados. Se encontrar algum, ele cria novas entradas de diretório e as coloca em "perdido + encontrado".
fonte
você pode usar
readlink FILE; echo $?
. Isso retorna 1 quando é um link físico e 0 quando é um link simbólico.Na página do manual: "Quando chamado como readlink, apenas o destino do link simbólico é impresso. Se o argumento fornecido não for um link simbólico, o readlink não imprimirá nada e sairá com um erro".
fonte