Verkrijg de thuismap van de gebruiker

Is het volgende de beste manier om de homedirectory van de actieve gebruiker te verkrijgen? Of is er een specifieke functie die ik heb genoten?

os.Getenv("HOME")

Als het bovenstaande correct is, weet iemand dan toevallig of deze aanpak gegarandeerd werkt op niet-Linux platforms, bijvoorbeeld Ramen?

64
$ HOME is niet noodzakelijkerwijs de basismap van de gebruiker. Ik kan bijvoorbeeld exporteren HOME =/something/else schrijven voordat je je programma start. Meestal betekent dit dat ik wil dat het programma om de een of andere reden /something/else als mijn persoonlijke map behandelt, en meestal moet het programma dat accepteren. Maar als u echt de werkelijke basismap van de gebruiker nodig heeft, geeft een omgevingsvariabele u dit niet noodzakelijk.
toegevoegd de auteur Keith Thompson, de bron
@KeithThompson Bedankt maar voor mijn doeleinden is het goed genoeg.
toegevoegd de auteur Paul Ruane, de bron

6 antwoord

In go 1.0.3 (waarschijnlijk eerder ook) werken de volgende werken:

package main
import (
    "os/user"
    "fmt"
    "log"
)
func main() {
    usr, err := user.Current()
    if err != nil {
        log.Fatal( err )
    }
    fmt.Println( usr.HomeDir )
}

If it is important to cross-compile, consider the homedir library

134
toegevoegd
Ben ik de enige of ben ik de enige die dit op Windows doet duurt enkele seconden?
toegevoegd de auteur Htbaa, de bron
Geweldig, heel erg bedankt. Was niet op de hoogte van deze verandering. Dit is precies wat ik zocht.
toegevoegd de auteur Paul Ruane, de bron
Het werkt op Mac OS 10.6.8 met Go-versies zo oud als 1.0.3, 32- en 64-bit.
toegevoegd de auteur George, de bron
Wees gewaarschuwd dat vanaf go 1.1, "usr, err: = user.Current ()" een "user: Current not geïmplementeerd op darwin/amd64" fout op osx zal gooien.
toegevoegd de auteur Oleiade, de bron
werkt niet wanneer cross gecompileerd code.google.com/p/go/issues/detail? id = 6376
toegevoegd de auteur Vishnu, de bron
Het lijkt absoluut onmiddellijk op mijn Windows 7 64bit VM.
toegevoegd de auteur Vlad Didenko, de bron

Bijvoorbeeld,

package main

import (
    "fmt"
    "os"
    "runtime"
)

func UserHomeDir() string {
    if runtime.GOOS == "windows" {
        home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
        if home == "" {
            home = os.Getenv("USERPROFILE")
        }
        return home
    }
    return os.Getenv("HOME")
}

func main() {
    dir := UserHomeDir()
    fmt.Println(dir)
}
13
toegevoegd
Dit is dezelfde benadering als Jeremy W Sherman, die op dit moment de enige manier lijkt te zijn. Erg bedankt.
toegevoegd de auteur Paul Ruane, de bron
Dit is de aanpak die wordt gevolgd in viper util.go userHomeDir()
toegevoegd de auteur ecerulm, de bron

Gebruik de omgevingsvariabele USERPROFILE of HOMEPATH onder Windows. Zie Erkende omgevingsvariabelen (een meer algemene documentatie) link zou worden toegejuicht).

2
toegevoegd
@PaulRuane Omdat de platforms verschillende variabelen gebruiken, negeert u het besturingssysteem, controleert u beide variabelen en gaat u met de gevraagde. Als beide zijn gedefinieerd, zou ik HOME gebruiken, omdat dat waarschijnlijk betekent dat u onder cygwin werkt.
toegevoegd de auteur Jeremy W. Sherman, de bron
Bedankt. Zeg je dan dat HOME niet wordt gevuld door Go voor elk platform (dat het rechtstreeks naar de O/S env vars delegeert) en ik moet de respectieve variabele van elk platform controleren om de homedirectory te identificeren?
toegevoegd de auteur Paul Ruane, de bron
Ik heb de bron bekeken en het lijkt erop dat HOME niet automatisch wordt ingevuld. Lijkt erop dat er (momenteel) geen platformonafhankelijke voorziening is voor het verkrijgen van de homedirectory.
toegevoegd de auteur Paul Ruane, de bron

Hier is een mooie, beknopte manier om het te doen (als je alleen draait op een UNIX-gebaseerd systeem):

import (
  "os"
)

var home string = os.Getenv("HOME")

Dat vraagt ​​alleen naar de $ HOME omgevingsvariabele.

--- Bewerk ---

Ik zie nu dat deze zelfde methode hierboven werd gesuggereerd. Ik laat dit voorbeeld hier achter als een gedistilleerde oplossing.

2
toegevoegd
1. het is eerder gesuggereerd, 2. het is geen platformoverschrijdend, 3. het geaccepteerde antwoord lost dit probleem al op een betere manier op.
toegevoegd de auteur Paul Ruane, de bron

Gelijkaardig antwoord op @peterSO maar respecteert het pad XDG_CONFIG_HOME voor linux.

package main

import (
    "fmt"
    "os"
    "runtime"
)

func userHomeDir() string {
    if runtime.GOOS == "windows" {
        home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
        if home == "" {
            home = os.Getenv("USERPROFILE")
        }
        return home
    } else if runtime.GOOS == "linux" {
        home := os.Getenv("XDG_CONFIG_HOME")
        if home != "" {
            return home
        }
    }
    return os.Getenv("HOME")
}

func main() {
    fmt.Println(userHomeDir())
}
1
toegevoegd

go1.8rc2 has the go/build/defaultGOPATH function which gets the home directory. https://github.com/golang/go/blob/go1.8rc2/src/go/build/build.go#L260-L277

De volgende code wordt uit de standaardGOPATH-functie geëxtraheerd.

package main

import (
    "fmt"
    "os"
    "runtime"
)

func UserHomeDir() string {
    env := "HOME"
    if runtime.GOOS == "windows" {
        env = "USERPROFILE"
    } else if runtime.GOOS == "plan9" {
        env = "home"
    }
    return os.Getenv(env)
}

func main() {
    dir := UserHomeDir()
    fmt.Println(dir)
}
1
toegevoegd
Hoewel de implementatie van deze Go-functie interessant is, is dit een slechtere oplossing dan het gebruik van de standaardbibliotheekfunctie die wordt beschreven in het geaccepteerde antwoord. (En is dezelfde benadering als het antwoord van peterSO van zes jaar geleden.)
toegevoegd de auteur Paul Ruane, de bron