readlink.go 961 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. //go:build linux || darwin
  2. package pathx
  3. import (
  4. "os"
  5. "path/filepath"
  6. )
  7. // ReadLink returns the destination of the named symbolic link recursively.
  8. func ReadLink(name string) (string, error) {
  9. name, err := filepath.Abs(name)
  10. if err != nil {
  11. return "", err
  12. }
  13. if _, err := os.Lstat(name); err != nil {
  14. return name, nil
  15. }
  16. // uncheck condition: ignore file path /var, maybe be temporary file path
  17. if name == "/" || name == "/var" {
  18. return name, nil
  19. }
  20. isLink, err := isLink(name)
  21. if err != nil {
  22. return "", err
  23. }
  24. if !isLink {
  25. dir, base := filepath.Split(name)
  26. dir = filepath.Clean(dir)
  27. dir, err := ReadLink(dir)
  28. if err != nil {
  29. return "", err
  30. }
  31. return filepath.Join(dir, base), nil
  32. }
  33. link, err := os.Readlink(name)
  34. if err != nil {
  35. return "", err
  36. }
  37. dir, base := filepath.Split(link)
  38. dir = filepath.Dir(dir)
  39. dir, err = ReadLink(dir)
  40. if err != nil {
  41. return "", err
  42. }
  43. return filepath.Join(dir, base), nil
  44. }