Verifique se dois caminhos estão apontando para o mesmo arquivo


12

Eu tenho um script para criar recursivamente links simbólicos no meu diretório pessoal para o meu diretório de configurações, para manter os arquivos sob controle de versão. Gostaria de pular arquivos que já estão vinculados por meio de um diretório pai. Ou seja, se eu tiver esses arquivos / diretórios:

~/foo/ -> ~/settings/foo/
~/settings/foo/
~/settings/foo/bar

, como verifico se ~ / foo / bar e ~ / settings / foo / bar são o mesmo arquivo?

Edit : D'oh, mais alguns minutos de pesquisa revelaram a resposta :readlink -f $path

Respostas:


6

Se dois arquivos tiverem o mesmo ID do dispositivo e inode, eles serão o mesmo arquivo. A statferramenta de linha de comando facilita a localização

if [ "$(stat -c "%d:%i" FILE1)" == "$(stat -c "%d:%i" FILE2)" ]`

...

isso funciona para arquivos com links simbólicos ou arquivos com links físicos.


5
Para seguir links simbólicos, você precisa stat -L.
Gilles 'SO- stop be evil'

Como @Gilles disse, sem a opção -L, você pode obter resultados errados em algumas distribuições
Olaseni

18

Muitos shells possuem um -efoperador para o testbuiltin (ou seu sinônimo [) para testar se dois caminhos apontam para o mesmo arquivo existente (seguindo os links simbólicos). Isso inclui bash, dash, pdksh, ksh88, ksh93 e zsh, mas não o POSIX sh. No bash, ksh ou zsh, você também pode usar -efna [[ … ]]construção condicional.

if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files

1
De acordo com minha página de manual, -ef faz exatamente a mesma coisa que a resposta de Rich Homolka.
User13852

2
@ user13852 -eftem a vantagem de ser mais portátil (também um pouco mais rápido, mas não para que você perceba na maioria das vezes). Por exemplo, ele funciona em * BSD, OSX, BusyBox e também em Linux / Cygwin (GNU). Também é mais claro, pois faz exatamente o que é necessário. A única vantagem que posso ver para ligar staté quando você não deseja seguir links simbólicos.
Gilles 'SO- stop be evil'

0

Para softlinks (criados com ln -s) você pode usar realpath. Porém, isso não funcionará para hardlinks.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.