如何查找公司链接

如何查找公司链接

macOS Catalina 在 APFS 文件系统中引入了“firmlinks”。有没有办法通过 CLI 工具确定 /Users 是否是 firmlink 以及它链接到哪里?我正在寻找类似于readlink符号链接的命令。

答案1

可以在文件 /usr/share/firmlinks 中找到系统 firmlink 列表。

在 macOS Catalina 版本 10.15.1 上,firmlinks 文件的内容如下所示:

/AppleInternal  AppleInternal
/Applications   Applications
/Library        Library
/System/Library/Caches  System/Library/Caches
/System/Library/Assets  System/Library/Assets
/System/Library/PreinstalledAssets      System/Library/PreinstalledAssets
/System/Library/AssetsV2        System/Library/AssetsV2
/System/Library/PreinstalledAssetsV2    System/Library/PreinstalledAssetsV2
/System/Library/CoreServices/CoreTypes.bundle/Contents/Library  System/Library/CoreServices/CoreTypes.bundle/Contents/Library
/System/Library/Speech  System/Library/Speech
/Users  Users
/Volumes        Volumes
/cores  cores
/opt    opt
/private        private
/usr/local      usr/local
/usr/libexec/cups       usr/libexec/cups
/usr/share/snmp usr/share/snmp

答案2

我也在找这个。与此同时,我求助于比较pwd -P(显示进程工作目录的物理路径) 的结果与 的结果df .,例如:

# cd /Users ; pwd -P ; df .; cd - >/dev/null
/Users
Filesystem   512-blocks       Used Available Capacity iused      ifree %iused  Mounted on
/dev/disk1s1 1953595632 1384119832 545065168    72% 1287392 9766690768    0%   /System/Volumes/Data

(最后cd -切换回原始目录,并打印出目录路径,因此重定向到/dev/null。)

请注意 的输出如何pwd -P表示/Users,而df表示它安装在 上/System/Volumes/Data

答案3

笔记:以下答案是部分不回答,因为 macOS 或 中的 firmlink 标志有问题stat。(非常欢迎提供解释或解决方案。)

XNU 的/sys/stat.h有一个旗帜对于公司链接(SF_FIRMLINK)。通常,您可以通过使用以下方式读取所有用户标志的十进制输出来检查标志:统计命令,将其转换为十六进制,并根据相应标志的十六进制值按位测试。

例如Applications,测试SF_NOUNLINK0x00100000):

filepath="/Applications"
flag_hex="0x00100000"
st_flags=$(printf '0x%x' $(stat -f %f "$filepath"))
[[ $((( $(echo "$st_flags") & $flag_hex ))) -eq 0 ]] && echo "Flag $flag_hex is *not* set" || echo "Flag $flag_hex is set"

这将打印该Flag 0x00100000 is set

相反,测试未设置的标志,例如UF_HIDDEN0x00008000),将导致否定结果,因为在我们的例子中/Applications不是一个隐藏文件。

filepath="/Applications"
flag_hex="0x00008000"
st_flags=$(printf '0x%x' $(stat -f %f "$filepath"))
[[ $((( $(echo "$st_flags") & $flag_hex ))) -eq 0 ]] && echo "Flag $flag_hex is *not* set" || echo "Flag $flag_hex is set"

然而,问题始于 firmlinks。让我们测试一下 firmlink 标志/Applications

filepath="/Applications"
flag_hex="0x00800000"
st_flags=$(printf '0x%x' $(stat -f %f "$filepath"))
[[ $((( $(echo "$st_flags") & $flag_hex ))) -eq 0 ]] && echo "Flag $flag_hex is *not* set" || echo "Flag $flag_hex is set"

这应该输出Flag 0x00800000 is set,但实际上没有。相反,它告诉我们该SF_FIRMLINK标志是不是设置,即使/Applications客观上是一个牢固的联系。

当你只看变量时$st_flags……

filepath="/Applications"
st_flags=$(printf '0x%x' $(stat -f %f "$filepath"))
echo "$st_flags"

...那么输出只是0x100000SF_NOUNLINK仅),而不是0x900000(组合SF_NOUNLINKSF_FIRMLINK)。

这意味着 macOS 没有写入此标志根本,即使它是在中定义的/sys/stat.h,或者(更有可能的是)Apple 故意将此标志排除在外statlstat等等。

无论如何,对于命令行,目前看来我们只能基于以下解决方案Hambly 的回答除非有人知道或可以创建一个无需使用 stat/lstat 即可读取这些文件标志的工具。您可能必须应用以下方法获取属性列表(),根据其手册页,它就像是“ stat(2) 的严重增强版本”。

对于命令行你可能还应该采取合成公司链接考虑到这一点。因此,快速解决方案 (firmlink yes|no) 应如下所示:

firmlinks=$(awk '{print $1}' < /usr/share/firmlinks)
synthetics=$(grep -v -e "^$" -e "\#" < "/etc/synthetic.conf" | awk '{print "/"$1}')
firmlinks=$(echo -e "$firmlinks\n$synthetics" | grep -v "^$" | sort)
for filepath in "$@"
do
    filepath=$(echo "$filepath" | sed 's-/$--')
    echo "$firmlinks" | grep -q "^$filepath$" &>/dev/null && echo "Firmlink: $filepath"
done

以下是打印实际链接信息的适当解决方案,例如Firmlink: /Users -> Users

firmlinks=$(cat /usr/share/firmlinks 2>/dev/null)
synthetics=$(grep -v -e "^$" -e "\#" < "/etc/synthetic.conf" 2>/dev/null | sed 's-^-/-g')
firmlinks=$(echo -e "$firmlinks\n$synthetics" | grep -v "^$" | sort)
for filepath in "$@"
do
    filepath=$(echo "$filepath/" | sed 's-/*$--')
    firmlink_raw=$(echo "$firmlinks" | grep "^$filepath\t")
    if [[ $firmlink_raw ]] ; then
        firmlink1=$(echo "$firmlink_raw" | awk -F\t '{print $1}')
        firmlink2=$(echo "$firmlink_raw" | awk -F\t '{print $2}')
        echo "Firmlink: $firmlink1 -> $firmlink2"
    fi
done

相关内容