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

l0b0
fonte

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.

Rich Homolka
fonte
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
Gilles 'SO- parar de ser mau'
fonte
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.

Benjamin Bannier
fonte