17

如何在 Go 中解析符号链接?

目前我打电话readlink -f,但我想要一些更惯用的东西。

package main

import (
    "os/exec"
    "fmt"
)

func resolve(p string) string {
    cmd := exec.Command("readlink", "-f", p)
    out, _ := cmd.Output()

    return (string(out))
}

func main() {
    fmt.Printf(resolve("/initrd.img"))
}
4

3 回答 3

33

请参阅filepath.EvalSymlinks()

EvalSymlinks 在评估任何符号链接后返回路径名。如果路径是相对的,则结果将相对于当前目录,除非其中一个组件是绝对符号链接。

例子

树:

/bin/sh -> bash
/usr/lib/libresolv.so -> ../../lib/libresolv.so.2

os.Readlink()

os.Readlink("/bin/sh") // => bash
os.Readlink("/usr/lib/libresolv.so") //=> ../../lib/libresolv.so.2

文件路径.EvalSymlinks()

filepath.EvalSymlinks("/bin/sh") // => /bin/bash
filepath.EvalSymlinks("/usr/lib/libresolv.so") //=> /lib/libresolv-2.20.so

注意:不是绝对路径(cd /bin

 filepath.EvalSymlinks("sh") // => bash
 filepath.EvalSymlinks("/bin/sh") // => /bin/bash

还有更多

 filepath.EvalSymlinks("/bin/bash") // => /bin/bash
 // but
 os.Readlink("/bin/bash") // => error: readlink /bin/bash: invalid argument

不适用于游乐场的示例应用程序

于 2015-01-31T06:47:23.837 回答
22

使用os.Lstat

func Lstat(name string) (fi FileInfo, err error)

Lstat 返回描述命名文件的 FileInfo。如果文件是符号链接,则返回的 FileInfo 描述符号链接。Lstat 不会尝试跟踪该链接。如果有错误,它将是 *PathError 类型。

编辑:

然后返回os.FileInfo将只允许您检查“名称”是否是链接(fi.Mode() & os.ModeSymlink != 0)。如果是,则使用os.Readlink获取指针:

func Readlink(name string) (string, error)

Readlink 返回命名符号链接的目的地。如果有错误,它将是 *PathError 类型。

于 2013-08-05T15:35:11.370 回答
0

我遇到的问题是filepath.EvalSymlinks()附加在 Mac 上/private/已解析的链接中/tmp/(也许符号链接不应该指向那里)。

另一方面, os.Readlink()在 Mac 上返回绝对路径,但在 Ubuntu 上返回相对路径。

因此,为了确保检索绝对路径,以下解决方案对我有用:

resolvedLink, _ := os.Readlink(someSymlink) // TODO: Handle error here
if !filepath.IsAbs(resolvedLink) { // Output of os.Readlink is OS-dependent...
    resolvedLink = path.Join(path.Dir(someSymlink), resolvedLink)
}
于 2022-02-16T12:52:31.743 回答