ユーザーのホームディレクトリを取得する


89

以下は、実行中のユーザーのホームディレクトリを取得する最良の方法ですか?それとも、私が見てきた特定の機能はありますか?

os.Getenv("HOME")

上記が正しい場合、誰かがたまたまこのアプローチがLinux以外のプラットフォーム(Windowsなど)で機能することが保証されているかどうかを知っていますか?


2
$HOME必ずしもユーザーのホームディレクトリではありません。たとえばexport HOME=/something/else、プログラムを起動する前に書くことができます。通常、これは、何らかの理由でプログラムをホームディレクトリとして扱いたいことを意味/something/elseします。通常、プログラムはそれを受け入れます。しかし、ユーザーの実際のホームディレクトリが本当に必要な場合は、環境変数が必ずしもそれを与えるとは限りません。
Keith Thompson

1
@KeithThompsonありがとうございますが、私の目的には十分です。
ポール・ルアン

回答:


173

go 1.0.3(おそらく以前にも)では、次のように動作します。

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

クロスコンパイルが重要な場合はライブラリを検討してくださいhomedir


1
すばらしい、ありがとう。この変化に気づかなかった。これはまさに私が探していたものです。
ポールルアン

Windowsでこれを行うのに数秒かかるのは私だけですか、それとも私だけですか?
Htbaa 2013

私のWindows 7 64ビットVMでは、間違いなくインスタントのようです。
Vlad Didenko 2013

4
go 1.1以降、osxで「usr、err:= user.Current()」を実行すると、「user:Currentがdarwin / amd64に実装されていない」というエラーがスローされることに注意してください。
Oleiade 2013

11
クロスコンパイルは動作しませんcode.google.com/p/go/issues/detail?id=6376
ヴィシュヌ

55

os.UserHomeDir()

go1.12 +では、os.UserHomeDir()を使用できます

home, err := os.UserHomeDir()

https://golang.org/pkg/os/#UserHomeDirを参照してください

これは、CGOが有効になっていない場合(つまりFROM scratch)でも、解析/etc/passwdや他のそのようなナンセンスを実行しなくても機能するはずです。


22

例えば、

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
これは、現在唯一の方法であると思われるジェレミーWシャーマンと同じアプローチです。どうもありがとう。
ポール・ルアン

2
これは、viper util.go userHomeDir()で採用さ
RubenLaguna

これが使用されているのを目にするほとんどすべての場合、これは正しいことではありませんUSERPROFILEシステム上のユーザーのストレージスペースのルートですが、アプリケーションが保存ダイアログプロンプトの外側に書き込む必要がある場所ではありません。アプリケーション設定がある場合はAPPDATA書き込みを行い、アプリケーションキャッシュ(またはネットワーク経由で同期してはならない大きなファイル)がある場合はLOCALAPPDATAWindowsに書き込む必要があります。
Micah Zoltu

4

これを行うには、簡潔で簡潔な方法があります(UNIXベースのシステムでのみ実行している場合)。

import (
  "os"
)

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

これは、$ HOME環境変数を照会するだけです。

---編集---

これと同じ方法が上記で提案されていることがわかりました。この例は、ここでは蒸留溶液のままにしておきます。


2
1.それは以前に提案されていました、2。それはクロスプラットフォームではありません、3。受け入れられた回答はすでにこの問題をより良い方法で解決しています。
Paul Ruane 2013年

3

@peterSOと同様の回答ですがXDG_CONFIG_HOME、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())
}

Windowsを尊重するためにこの回答が更新されるのを見てみたいです! APPDATA構成用およびLOCALAPPDATA大きなファイル用。一般的な目的の「ホーム」にはLOCALAPPDATA、デフォルトでアプリケーション開発者が企業ネットワークを破壊しないようにすることをお勧めします。😊
ミカZoltu

2

環境変数を使用するUSERPROFILEHOMEPATH、Windowsで使用する必要があります。認識される環境変数を参照してください(より適切なドキュメントリンクを歓迎します)。


ありがとう。では、HOMEは各プラットフォームのGoによって(O / S env varsに直接委任されて)作成されておらず、ホームディレクトリを特定するために各プラットフォームのそれぞれの変数を確認する必要があるということですか?
Paul Ruane、2011年

ソースを確認したところ、HOMEが自動的に入力されていないようです。現在のところ、ホームディレクトリを取得するためのプラットフォームに依存しない機能はないようです。
Paul Ruane、2011年

@PaulRuaneプラットフォームは異なる変数を使用するため、OSを無視して両方の変数を確認し、入力された方の変数を使用してください。両方が定義されている場合はHOME、おそらくcygwinで実行していることを意味するので、を使用します。
ジェレミーW.シャーマン、

あなたは必要がありませ使うUSERPROFILEか、HOMEPATH大多数の場合、Windows上で。開発者がそれらを使用するほとんどすべての場合、使用する必要があるのはAPPDATAまたはですLOCALAPPDATA(ログイン/ログアウト時にコンテンツがネットワーク経由で同期することが妥当かどうかによって異なります)。
Micah Zoltu

2

go1.8rc2には、ホームディレクトリを取得するgo / build / defaultGOPATH関数があります。 https://github.com/golang/go/blob/go1.8rc2/src/go/build/build.go#L260-L277

次のコードは、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)
}

このGo関数の実装は興味深いものですが、これは受け入れられた回答で説明されている標準ライブラリ関数を使用するよりも悪い解決策です。(そして、6年前からのpeterSOの回答と同じアプローチです。)
Paul

ほとんどの場合、これは適切なソリューションではありません。他の回答にコメントを参照してくださいが、TL; DRは、ということですAPPDATAか、LOCALAPPDATAほとんど常に正しい選択ではないUSERPROFILEWindows上で、。
Micah Zoltu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.