Bash 如何在Mac OS中使用脚本检测文件是别名还是源文件

Bash 如何在Mac OS中使用脚本检测文件是别名还是源文件,bash,macos,shell,finder,Bash,Macos,Shell,Finder,我正在编写一个脚本来检测一个文件是否是另一个文件的别名,如下所示,但别名的概念似乎与符号链接不同 我怎样才能让它工作呢 filePath=./aliasfile echo $filePath if [ -e "$filePath" ]; then if [ ! -L "$filePath" ] then echo "$filePath is not alias" else echo "$filePath is alias" fi e

我正在编写一个脚本来检测一个文件是否是另一个文件的别名,如下所示,但别名的概念似乎与符号链接不同

我怎样才能让它工作呢

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

别名和符号链接在概念上非常相似,但在细节上有很大不同。macOS之所以有两种不同的方式来做本质上相同的事情,是因为它的历史:它是“经典”macOS(MacOS9及其前身)和unix的后代。“别名”文件是经典Mac OS创建快捷方式文件的方式的后代,符号链接是Unix创建文件系统快捷方式的方式。为了兼容性(以及一定程度的灵活性),macOS同时支持这两种功能

大多数情况下:unix(/POSIX)API只识别符号链接,并将别名视为普通文件。这就是为什么
-L
测试无法识别别名文件的原因

我最初建议通过和来识别alias文件,但在调查了@Toby的一条评论后,发现这比我想象的要复杂得多。在macOS的最新版本中,文件的别名类型为“alis”,创建者为“MACS”,但文件夹的别名类型为“fdrp”,应用程序的别名类型为“fapa”。在旧版本中,我发现了类型为“adrp”和creator从原始应用复制的应用的别名,以及类型代码为空(!)的文件的别名。可能还有其他的组合,所以我不再推荐这个了

相反,托比的建议似乎效果很好:
mdls-raw-name kMDItemContentType/path/to/file
将为别名文件打印“com.apple.alias file”

下面是我更新的脚本:

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

具有别名文件格式的说明。也许
文件
可以识别它?在10.15 Catalina上似乎不再有效(不确定以前的版本)。FinderInfo扩展属性有一个
fdrpMACS
前缀,而不是
alisMACS
,我确保创建一个查找器别名而不是符号链接。我的替代方法是:
mdls-raw-name kMDItemContentType
。它将返回查找器别名的
com.apple.alias文件
。@Toby显然它根据原始项的类型使用不同的类型代码(并且在不同的操作系统版本之间有所更改,但不是最近)。因此,我更新了我的答案,以使用您的
mdls
方法。