Dapatkan direktori home pengguna


94

Apakah berikut cara terbaik untuk mendapatkan direktori home pengguna yang sedang berjalan? Atau adakah fungsi tertentu yang telah saya lihat?

os.Getenv("HOME")

Jika hal di atas benar, adakah yang kebetulan mengetahui apakah pendekatan ini dijamin bekerja pada platform non-Linux, misalnya Windows?


2
$HOMEbelum tentu direktori home pengguna. Misalnya, saya bisa menulis export HOME=/something/elsesebelum meluncurkan program Anda. Biasanya itu berarti saya ingin program diperlakukan /something/elsesebagai direktori home saya karena alasan tertentu, dan biasanya program harus menerimanya. Tetapi jika Anda benar-benar membutuhkan direktori home sebenarnya dari pengguna , variabel lingkungan tidak akan selalu memberikannya kepada Anda.
Keith Thompson

1
@Keompson Terima kasih, tetapi untuk tujuan saya itu cukup baik.
Paul Ruane

Jawaban:


176

Dalam go 1.0.3 (mungkin lebih awal, juga) bekerja berikut:

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

Jika penting untuk cross-kompilasi, pertimbangkan yang homedirperpustakaan


1
Luar biasa, terima kasih banyak. Tidak menyadari perubahan ini. Inilah yang saya cari.
Paul Ruane

Apakah hanya saya atau saya satu-satunya yang melakukan ini di Windows membutuhkan waktu beberapa detik?
Htbaa

Tampaknya instan di VM Windows 7 64bit saya.
Vlad Didenko

4
Ketahuilah bahwa mulai 1.1, "usr, err: = user.Current ()" akan memunculkan kesalahan "pengguna: Saat ini tidak diterapkan pada darwin / amd64" di osx.
Oleiade

11
tidak berfungsi ketika kode yang
Wisnu

61

os.UserHomeDir ()

Di go1.12 + Anda dapat menggunakan os.UserHomeDir ()

home, err := os.UserHomeDir()

Lihat https://golang.org/pkg/os/#UserHomeDir

Itu harus bekerja bahkan tanpa CGO diaktifkan (yaitu FROM scratch) dan tanpa harus mengurai /etc/passwdatau omong kosong semacam itu.


23

Sebagai contoh,

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)
}

1
Ini adalah pendekatan yang sama dengan Jeremy W. Sherman yang tampaknya menjadi satu-satunya cara saat ini. Terimakasih banyak.
Paul Ruane

2
Ini adalah pendekatan yang diikuti di viper util.go userHomeDir ()
RubenLaguna

Dalam hampir semua kasus di mana saya melihat ini digunakan, ini BUKAN hal yang benar untuk dilakukan. USERPROFILEadalah root dari ruang penyimpanan Pengguna di sistem, tetapi BUKAN tempat di mana aplikasi harus menulis di luar prompt dialog simpan. Jika Anda memiliki konfigurasi aplikasi, konfigurasi tersebut harus ditulis ke APPDATAdan jika Anda memiliki cache aplikasi (atau file besar yang tidak boleh disinkronkan melalui jaringan) , konfigurasi tersebut harus ditulis LOCALAPPDATAdi Windows.
Mikha Zoltu

4

Berikut adalah cara yang bagus dan ringkas untuk melakukannya (jika Anda hanya menjalankan sistem berbasis UNIX):

import (
  "os"
)

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

Itu hanya menanyakan variabel lingkungan $ HOME.

--- Edit ---

Sekarang saya melihat bahwa metode yang sama disarankan di atas. Saya akan meninggalkan contoh ini di sini sebagai solusi suling.


2
1. sudah disarankan sebelumnya, 2. bukan lintas platform, 3. jawaban yang diterima sudah menyelesaikan masalah ini dengan cara yang lebih baik.
Paul Ruane

3

Jawaban serupa untuk @peterSO tetapi menghormati XDG_CONFIG_HOMEjalur untuk 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())
}

Akan sangat senang melihat jawaban ini diperbarui untuk menghormati Windows juga! APPDATAuntuk konfigurasi dan LOCALAPPDATAuntuk file besar. Untuk tujuan umum "rumah", saya sarankan LOCALAPPDATAagar secara default pengembang aplikasi tidak merusak jaringan perusahaan. 😊
Mikha Zoltu

2

Anda harus menggunakan variabel lingkungan USERPROFILEatau di HOMEPATHbawah Windows. Lihat Variabel Lingkungan yang Diakui (tautan dokumentasi yang lebih tepat akan disambut).


Terima kasih. Apakah Anda mengatakan, bahwa HOME tidak diisi oleh Go untuk setiap platform (yang didelegasikan langsung ke dalam O / S env vars) dan saya harus memeriksa variabel masing-masing platform untuk mengidentifikasi direktori home?
Paul Ruane

Saya telah melihat sumbernya dan tampaknya HOME tidak terisi secara otomatis. Sepertinya (saat ini) tidak ada fasilitas agnostik platform untuk mendapatkan direktori home.
Paul Ruane

@PaulRuane Karena platform menggunakan variabel yang berbeda, abaikan saja OS, periksa kedua variabel, dan gunakan variabel mana saja yang terisi. Jika keduanya didefinisikan, saya akan menggunakan HOME, karena itu mungkin berarti Anda menjalankan cygwin.
Jeremy W. Sherman

Anda TIDAK boleh menggunakan USERPROFILEatau HOMEPATHdi Windows dalam sebagian besar kasus. Dalam hampir semua kasus di mana devs menggunakan itu, apa yang seharusnya mereka gunakan adalah APPDATAatau LOCALAPPDATA(tergantung pada apakah konten tersebut masuk akal untuk disinkronkan melalui jaringan saat login / logout).
Mikha Zoltu

2

go1.8rc2 memiliki fungsi go / build / defaultGOPATH yang mendapatkan direktori home. https://github.com/golang/go/blob/go1.8rc2/src/go/build/build.go#L260-L277

Kode berikut diekstrak dari fungsi defaultGOPATH.

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)
}

Meskipun penerapan fungsi Go ini menarik, ini adalah solusi yang lebih buruk daripada menggunakan fungsi pustaka standar yang dijelaskan dalam jawaban yang diterima. (Dan merupakan pendekatan yang sama dengan jawaban peterSO dari enam tahun lalu.)
Paul Ruane

Ini bukanlah solusi yang tepat dalam banyak kasus . Lihat komentar di jawaban lain, tetapi TL; DR adalah itu APPDATAatau LOCALAPPDATAhampir selalu merupakan pilihan yang tepat, bukan USERPROFILE, di Windows.
Mikha Zoltu
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.