Eu tenho um script para criar links simbólicos recursivamente em meu diretório inicial para meu diretório de configurações, para manter os arquivos sob controle de versão. Eu gostaria que ele ignorasse os arquivos que já estão vinculados simbolicamente por meio de um diretório pai. Isto é, se eu tiver esses arquivos/diretórios:
~/foo/ -> ~/settings/foo/
~/settings/foo/
~/settings/foo/bar
, como posso verificar se ~/foo/bar e ~/settings/foo/bar são o mesmo arquivo?
Editar: D'oh, mais alguns minutos de busca revelaram oresponder:readlink -f $path
Responder1
Se dois arquivos tiverem o mesmo deviceID e inode, eles serão o mesmo arquivo. A stat
ferramenta de linha de comando facilita a localização e esta solução é compatível com shell POSIX.
if [ "$(stat -L -c %d:%i FILE1)" = "$(stat -L -c %d:%i FILE2)" ]; then
echo "FILE1 and FILE2 refer to a single file, with one inode, on one device."
else
echo "no match"
fi
O -L
sinalizador em cada um stat
significa que isso funciona para arquivos com link simbólico e físico.
Responder2
Muitos shells possuem um -ef
operador para o test
builtin (ou seu sinônimo [
) para testar se dois caminhos apontam para omesmo arquivo existente(seguindo links simbólicos). Isso inclui bash, dash, pdksh, ksh88, ksh93 e zsh, mas não POSIX sh. No bash, ksh ou zsh, você também pode usar -ef
na [[ … ]]
construção condicional.
if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files
Responder3
Para softlinks (criados com ln -s
) você pode usar realpath
. Porém, isso não funcionará para hardlinks.