exec.LookPath în Go

Caută un program executabil în directoarele din PATH și returnează calea lui.

Sintaxă
func LookPath(file string) (string, error)

Ce face exec.LookPath

exec.LookPath face ce face shell-ul când scrii o comandă: caută file în fiecare director din PATH și returnează prima cale găsită care este executabilă. Dacă file conține un separator (./script.sh, /usr/bin/git), nu mai caută, ci verifică direct acea cale.

Este utilă ca să verifici la pornire că un program necesar (ffmpeg, git) este instalat. Din Go 1.19, LookPath refuză programele găsite printr-o intrare relativă din PATH (de exemplu . sau bin) și returnează o eroare pentru care errors.Is(err, exec.ErrDot) este true. Așa nu pornești din greșeală un program cu același nume aflat în directorul curent.

Parametri

Parametru Descriere
file Numele programului.

Ce returnează

Calea programului și nil, sau o eroare (exec.ErrNotFound împachetat).

Exemple

Exemplul 1: Verificarea programelor necesare

Rezultatul depinde de ce este instalat pe calculator.

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    for _, p := range []string{"git", "ffmpeg", "sh"} {
        cale, err := exec.LookPath(p)
        if err != nil {
            fmt.Printf("%-7s lipsește\n", p)
            continue
        }
        fmt.Printf("%-7s %s\n", p, cale)
    }
}

Rezultat posibil (diferă la fiecare rulare)

git     /usr/bin/git
ffmpeg  lipsește
sh      /bin/sh

Exemplul 2: Căutare controlată în PATH

Setăm PATH la un director propriu, cu un script executabil. Un fișier fără drept de execuție nu este găsit, iar un director relativ în PATH este refuzat cu exec.ErrDot.

package main

import (
    "errors"
    "fmt"
    "os"
    "os/exec"
    "path/filepath"
)

func main() {
    os.Mkdir("bin", 0o755)
    os.WriteFile("bin/raport", []byte("#!/bin/sh\necho raport generat\n"), 0o755)
    os.WriteFile("bin/nota.txt", []byte("nu e executabil"), 0o644)

    dir, _ := filepath.Abs("bin")
    os.Setenv("PATH", "/nu/exista:"+dir)
    cale, err := exec.LookPath("raport")
    fmt.Println(filepath.Base(cale), err)

    _, err = exec.LookPath("nota.txt")
    fmt.Println(err)
    fmt.Println("ErrNotFound:", errors.Is(err, exec.ErrNotFound))

    os.Setenv("PATH", "bin") // director relativ în PATH
    _, err = exec.LookPath("raport")
    fmt.Println(err)
    fmt.Println("ErrDot:", errors.Is(err, exec.ErrDot))
}

Rezultat

raport <nil>
exec: "nota.txt": executable file not found in $PATH
ErrNotFound: true
exec: "raport": cannot run executable found relative to current directory
ErrDot: true

Greșeli frecvente

  • Verifici cu LookPath și apoi rulezi altceva. Folosește direct calea returnată în exec.Command.

Comenzi înrudite

  • exec.Command: Pregătește rularea unui program extern cu argumentele date; programul pornește abia la Run, Output sau Start.
  • filepath.SplitList: Împarte o listă de căi precum $PATH după separatorul de listă al sistemului (: pe Unix, ; pe Windows).
  • os.Getenv: Returnează valoarea unei variabile de mediu sau textul gol dacă variabila nu există.