Check if two paths are pointing to the same file
I've got a script to recursively create symlinks in my home directory to my settings directory, to keep the files under version control. I would like it to skip files which are already symlinked via a parent directory. That is, if I have these files/directories:
~/foo/ -> ~/settings/foo/
~/settings/foo/
~/settings/foo/bar
, how do I check that ~/foo/bar and ~/settings/foo/bar are the same file?
Edit: D'oh, another few minutes of searching revealed the answer: readlink -f $path
Solution 1:
If two files have the same deviceID and inode, they're the same file. The stat
command line tool makes this easy to find and this solution is POSIX shell-compliant.
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
The -L
flag in each stat
means this works for both symlinked and hardlinked files.
Solution 2:
Many shells have a -ef
operator for the test
builtin (or its synonym [
) to test whether two paths point to the same existing file (following symbolic links). This includes bash, dash, pdksh, ksh88, ksh93 and zsh, but not POSIX sh. In bash, ksh or zsh, you can also use -ef
in the [[ … ]]
conditional construct.
if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files