如何测试位置是否是btrfs子卷?

vaa*_*aab 5 bash btrfs

在bash脚本中,如果特定位置是btrfs子卷,我怎么能优雅地检查?

我不想知道给定的位置是否在 btrfs文件系统(或子卷)中.我想知道给定的位置是否是子体积的头部.

理想情况下,解决方案可以用bash函数编写,所以我可以写:

if is_btrfs_subvolume $LOCATION; then
    # ... stuff ...
fi 
Run Code Online (Sandbox Code Playgroud)

"优雅"解决方案可读,代码小,资源消耗小.

kda*_*ave 11

子卷由inode编号256标识,因此您可以简单地检查它

if [ `stat --format=%i /path` -eq 256 ]; then ...; fi
Run Code Online (Sandbox Code Playgroud)

还有一个所谓的空子体积,即.如果嵌套的子卷被快照,则该实体将代替原始子卷存在.它的inode数是2.

对于通常可靠的检查,任何目录都是子卷,也应该验证文件系统类型

stat -f --format=%T /path
Run Code Online (Sandbox Code Playgroud)

  • 命令"btrfs subvolume list"需要root权限,因为它使用特权ioctl来读取有关子卷的信息,这在原始答案中没有被删除.基于inode数量的测试没有这样的限制.接下来,我不明白你的意思是"如果使用任何新的inode号码就会变脆".每个子卷的索引节点号为256,这不会改变.子卷中的常规文件和目录的索引节点号为257或更高. (2认同)

vaa*_*aab 5

解决方案 1:使用 @kdave 建议:

is_btrfs_subvolume() {
    local dir=$1
    [ "$(stat -f --format="%T" "$dir")" == "btrfs" ] || return 1
    inode="$(stat --format="%i" "$dir")"
    case "$inode" in
        2|256)
            return 0;;
        *)
            return 1;;
    esac
}
Run Code Online (Sandbox Code Playgroud)

解决方案2:我之前使用的(只有一次调用,但可能很脆弱):

is_btrfs_subvolume() {
    btrfs subvolume show "$1" >/dev/null 2>&1
}
Run Code Online (Sandbox Code Playgroud)

编辑:更正并替换list由show作为的行为list将无法正确回答任何正常的btrfs目录。

EDIT2:由于@kdave 没有发布他的高级答案的完整版本,我将其添加到我的答案中。