Golang中检查目录是否为挂载点的方法

Golang中检查目录是否为挂载点的方法 如何检查某个目录是否为挂载点,以及挂载点背后的设备是什么?

6 回复

什么操作系统?使用哪种挂载方式:FAT驱动器、WebDAV、CIFS……?

更多关于Golang中检查目录是否为挂载点的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


  • Linux(红帽企业版和Ubuntu)
  • 多路径设备(例如:/dev/mapper/mpathd)
  • 挂载点上的文件系统不太相关,只想知道dirX是否为挂载点,如果是,该挂载点的设备是什么?

也许 os.File.Stat() 包含一些有用的信息?

它返回一个 os.FileInfo

您可以解析 /proc/self/mountinfo 来获取所有挂载点及其后备设备的列表。

然后或许可以使用 multipath 来获取您需要的更多信息。

我可以做一些简单的事情,比如:

func getMount(mountdir string) (string, error){
res, err := exec.Command("sh", "-c", fmt.Sprintf("mount | grep -w %s", mountdir)).Output()
if err != nil{
return "", err
}
lines := strings.Split(string(res[:]), "\n")
if len(lines) != 1{
return "", fmt.Errorf("bad mount output")
}
fields := strings.Fields(lines[0])
if len(fields) != 6{
return "", fmt.Errorf("bad mount line formating")
}
device=fields[0]
return device, nill
}

但当然,用Go语言的方式来实现会更好。

在Go语言中,检查目录是否为挂载点以及获取挂载点背后的设备信息,可以通过解析系统文件(如Linux下的/proc/mounts/etc/mtab)来实现。以下是一个完整的示例代码,展示了如何实现这一功能。代码适用于类Unix系统(如Linux),并依赖于osbufio包来读取和解析挂载信息。

代码实现

package main

import (
    "bufio"
    "fmt"
    "os"
    "path/filepath"
    "strings"
)

// isMountPoint 检查给定目录是否为挂载点,并返回设备路径(如果是挂载点)
func isMountPoint(dir string) (bool, string, error) {
    // 规范化目录路径,处理符号链接等
    resolvedDir, err := filepath.EvalSymlinks(dir)
    if err != nil {
        return false, "", fmt.Errorf("无法解析目录路径: %v", err)
    }
    resolvedDir, err = filepath.Abs(resolvedDir)
    if err != nil {
        return false, "", fmt.Errorf("无法获取绝对路径: %v", err)
    }

    // 打开 /proc/mounts 文件(Linux系统)
    file, err := os.Open("/proc/mounts")
    if err != nil {
        return false, "", fmt.Errorf("无法打开 /proc/mounts: %v", err)
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        line := scanner.Text()
        fields := strings.Fields(line)
        if len(fields) < 2 {
            continue // 跳过格式不正确的行
        }
        device := fields[0]   // 设备路径,如 /dev/sda1
        mountPoint := fields[1] // 挂载点路径

        // 比较解析后的挂载点与目标目录
        if mountPoint == resolvedDir {
            return true, device, nil
        }
    }

    if err := scanner.Err(); err != nil {
        return false, "", fmt.Errorf("读取 /proc/mounts 时出错: %v", err)
    }

    // 未找到匹配的挂载点
    return false, "", nil
}

func main() {
    dir := "/mnt/external" // 替换为要检查的目录路径
    isMount, device, err := isMountPoint(dir)
    if err != nil {
        fmt.Printf("错误: %v\n", err)
        return
    }
    if isMount {
        fmt.Printf("目录 %s 是挂载点,设备为: %s\n", dir, device)
    } else {
        fmt.Printf("目录 %s 不是挂载点\n", dir)
    }
}

代码说明

  • 函数isMountPoint:接受一个目录路径作为参数,返回三个值:
    • 布尔值:指示该目录是否为挂载点。
    • 字符串:如果为挂载点,则返回对应的设备路径(如/dev/sda1);否则为空字符串。
    • 错误:在解析路径或读取文件过程中遇到问题时返回。
  • 路径处理:使用filepath.EvalSymlinksfilepath.Abs来解析符号链接并获取绝对路径,确保与/proc/mounts中的条目正确匹配。
  • 解析/proc/mounts:该文件在Linux系统中包含当前挂载点信息。每行格式为:设备 挂载点 文件系统类型 选项 ...,代码提取前两个字段进行比较。
  • 错误处理:包括路径解析失败、文件打开失败和读取错误。

使用示例

假设要检查目录/mnt/external是否为挂载点,运行上述代码后,输出可能为:

  • 如果是挂载点:目录 /mnt/external 是挂载点,设备为: /dev/sdb1
  • 如果不是挂载点:目录 /mnt/external 不是挂载点

此方法依赖于系统文件,因此在非Linux系统上可能需要调整(例如,在macOS上使用/etc/mtab或系统调用)。如果目录不存在或无权访问,函数将返回相应错误。

回到顶部