I'm writing a script to detect whether a file is an alias of another file like below, but it seems the alias is not same concept as symlink.
How could I get this to work?
filePath=./aliasfile
echo $filePath
if [ -e "$filePath" ]; then
if [ ! -L "$filePath" ]
then
echo "$filePath is not alias"
else
echo "$filePath is alias"
fi
else
echo "=> $filePath doesn't exist"
fi
Aliases and symbolic links are fairly similar in concept, but quite a bit different in detail. The reason macOS has two different ways to do essentially the same thing is because of its history: it descends from both "classic" Mac OS (Mac OS 9 and its predecessors) and unix. The "alias" file is a descendant of the way classic Mac OS did shortcut files, and symbolic links are the way unixes do filesystem shortcuts. For compatibility (and to some extent flexibility) macOS supports both.
Well, mostly: the unix (/POSIX) APIs only recognize symlinks, and treat aliases as plain files. This is why the -L
test doesn't recognize alias files.
I originally recommended recognizing alias files by their type and creator codes, but after investigating a comment from @Toby, that turned out to be much more complicated than I realized. Under recent versions of macOS, aliases of files have type "alis" and creator "MACS", but aliases of folders have type "fdrp" and aliases of apps have type "fapa". Under older versions, I found aliases of apps with type "adrp" and creator copied from the original app, and aliases of files with null type code(!). There may be other combinations, so I'm not going to recommend this anymore.
Instead, Toby's suggestion seems to work well: mdls -raw -name kMDItemContentType /path/to/file
will print "com.apple.alias-file" for alias files.
So here's my updated script:
filePath=./aliasfile
echo "$filePath" # You should (almost) always double-quote variable references
if [ ! -e "$filePath" ]
then
echo "=> $filePath doesn't exist"
elif [ -L "$filePath" ]
then
echo "$filePath is alias (well, technically a symlink)"
elif [ -f "$filePath" ] &&
mdls -raw -name kMDItemContentType "$filePath" 2>/dev/null | grep -q '^com\.apple\.alias-file$'
then
echo "$filePath is alias (a Finder-style one)"
else
echo "$filePath is not alias"
fi