os.Symlink în Go

Creează o legătură simbolică (scurtătură) spre alt fișier; Readlink citește spre ce arată.

Sintaxă
func Symlink(oldname, newname string) error
func Readlink(name string) (string, error)

Ce face os.Symlink

os.Symlink creează fișierul special newname, care arată spre oldname, ca ln -s. Când deschizi legătura, sistemul o urmează până la fișierul țintă. Ținta poate fi un director, poate fi pe alt disc și poate chiar să nu existe (legătură „ruptă”).

Ținta este salvată exact cum ai scris-o. O cale relativă se interpretează față de directorul în care se află legătura, nu față de directorul curent.

os.Readlink returnează textul țintei, fără să o urmeze. os.Lstat descrie legătura însăși, iar os.Stat descrie fișierul spre care arată.

Parametri

Parametru Descriere
oldname Ținta legăturii (ce va fi deschis).
newname Numele legăturii noi.
name La Readlink: legătura de citit.

Ce returnează

Symlink: nil sau eroarea. Readlink: ținta ca text și nil, sau eroare dacă name nu este legătură simbolică.

Exemple

Exemplul 1: Creare, citire și urmare

package main

import (
    "fmt"
    "os"
)

func main() {
    os.WriteFile("config-2025.json", []byte(`{"port": 8080}`), 0o644)
    if err := os.Symlink("config-2025.json", "config.json"); err != nil {
        fmt.Println("eroare:", err)
        return
    }

    tinta, _ := os.Readlink("config.json")
    fmt.Println("config.json arată spre:", tinta)

    date, _ := os.ReadFile("config.json") // urmează legătura
    fmt.Println("conținut:", string(date))

    info, _ := os.Lstat("config.json")
    fmt.Println("este legătură:", info.Mode()&os.ModeSymlink != 0)
}

Rezultat

config.json arată spre: config-2025.json
conținut: {"port": 8080}
este legătură: true

Exemplul 2: Legătură ruptă

După ștergerea țintei, legătura există încă, dar deschiderea ei eșuează.

package main

import (
    "fmt"
    "os"
)

func main() {
    os.WriteFile("ultima.log", []byte("..."), 0o644)
    os.Symlink("ultima.log", "curent.log")
    os.Remove("ultima.log")

    tinta, err := os.Readlink("curent.log")
    fmt.Println("Readlink:", tinta, err)

    _, err = os.ReadFile("curent.log")
    fmt.Println("ReadFile:", err)
}

Rezultat

Readlink: ultima.log <nil>
ReadFile: open curent.log: no such file or directory

Exemplul 3: Readlink pe un fișier obișnuit

package main

import (
    "fmt"
    "os"
)

func main() {
    os.WriteFile("simplu.txt", []byte("text"), 0o644)
    _, err := os.Readlink("simplu.txt")
    fmt.Println(err)
}

Rezultat

readlink simplu.txt: invalid argument

Greșeli frecvente

  • Inversezi argumentele: primul este ținta, al doilea legătura nouă (aceeași ordine ca la ln -s tinta legatura).
  • Dai o țintă relativă calculată față de directorul curent, dar legătura stă în alt director. Ținta relativă se rezolvă față de directorul legăturii.
  • Pe Windows, crearea legăturilor simbolice cere drepturi speciale (sau modul Developer).

Comenzi înrudite

  • os.Link: Creează o legătură hard: un al doilea nume pentru același fișier de pe disc.
  • filepath.EvalSymlinks: Returnează calea reală, după ce urmează toate legăturile simbolice din ea.
  • os.Chown: Schimbă proprietarul și grupul unui fișier; Lchown face același lucru pentru o legătură simbolică.
  • os.SameFile: Spune dacă două FileInfo descriu același fișier de pe disc, chiar dacă au căi diferite.