사용자의 홈 디렉토리 얻기


93

다음은 실행중인 사용자의 홈 디렉토리를 얻는 가장 좋은 방법입니까? 아니면 내가 간과했던 특정 기능이 있습니까?

os.Getenv("HOME")

위의 내용이 맞다면이 접근 방식이 비 Linux 플랫폼 (예 : Windows)에서 작동하는 것이 보장되는지 아는 사람이 있습니까?


2
$HOME반드시 사용자의 홈 디렉토리 는 아닙니다 . 예를 들어, export HOME=/something/else프로그램을 시작하기 전에 쓸 수 있습니다 . 일반적으로 이것은 어떤 이유로 프로그램이 내 홈 디렉토리 로 취급 되기를 원한다는 것을 의미 /something/else하며 일반적으로 프로그램은 그것을 받아 들여야합니다. 그러나 사용자의 실제 홈 디렉토리 가 정말로 필요한 경우 환경 변수가 반드시이를 제공하지는 않습니다.
— Keith Thompson 11

1
@KeithThompson 감사하지만 제 목적을 위해 충분합니다.
— 폴 Ruane

답변:


175

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
정말 감사합니다. 이 변화를 인식하지 못했습니다. 이것이 바로 제가 찾던 것입니다.
— 폴 Ruane

Windows에서이 작업을 수행하는 데 몇 초가 걸리는 유일한 사람입니까?
— Htbaa

내 Windows 7 64 비트 VM에서는 확실히 즉각적인 것 같습니다.
— Vlad Didenko 2013

4
go 1.1에서 "usr, err : = user.Current ()"는 osx에서 "user : Current not Implement on darwin / amd64"오류를 발생시킵니다.
— Oleiade

11
크로스 컴파일이 작동하지 않습니다 code.google.com/p/go/issues/detail?id=6376
— 비슈누

59

os.UserHomeDir ()

go1.12 +에서는 os.UserHomeDir ()을 사용할 수 있습니다.

home, err := os.UserHomeDir()

참조 https://golang.org/pkg/os/#UserHomeDir를

CGO를 사용하지 않고 (예 :) FROM scratch구문 분석 /etc/passwd하거나 다른 말도 안되는 일 없이도 작동 합니다.


23

예를 들면

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
이것은 현재 유일한 방법으로 보이는 Jeremy W Sherman과 동일한 접근 방식입니다. 감사합니다.
— 폴 Ruane

2
이것은 util.go 독사에 따라 접근 방법이다 userHomeDir ()
— RubenLaguna

이것이 사용되는 거의 모든 경우에 이것은 올바른 일 이 아닙니다 . USERPROFILE시스템에있는 사용자 저장 공간의 루트이지만 응용 프로그램이 저장 대화 상자 외부에 기록해야하는 위치 는 아닙니다 . 응용 프로그램 구성이있는 경우에는 작성해야하며 APPDATA응용 프로그램 캐시 (또는 네트워크를 통해 동기화하면 안되는 대용량 파일)가있는 경우 LOCALAPPDATAWindows에서 작성해야합니다 .
— Micah Zoltu

4

다음은이를 수행하는 훌륭하고 간결한 방법입니다 (UNIX 기반 시스템에서만 실행중인 경우).

import (
  "os"
)

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

$ HOME 환경 변수를 쿼리합니다.

--- 편집하다 ---

이제 위와 동일한 방법이 제안되었음을 알 수 있습니다. 이 예는 여기에 증류 용액으로 남겨 두겠습니다.


2
1. 이전에 제안 된 적이 있습니다. 2. 크로스 플랫폼이 아닙니다. 3. 받아 들여진 대답은 이미이 문제를 더 나은 방식으로 해결합니다.
— 폴 Ruane

3

@peterSO와 비슷한 대답이지만 XDG_CONFIG_HOMELinux 의 경로를 존중합니다 .

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기본적으로 응용 프로그램 개발자가 기업 네트워크를 망가 뜨리지 않도록 권장 합니다. 😊
— Micah Zoltu

2

환경 변수 USERPROFILE또는 HOMEPATHWindows에서 사용해야합니다 . 인식 된 환경 변수를 참조하십시오 (더 적절한 문서 링크를 환영합니다).


감사. 그렇다면 HOME은 각 플랫폼에 대해 Go에 의해 채워지지 않으며 (O / S 환경 변수에 직접 위임 됨) 홈 디렉토리를 식별하기 위해 각 플랫폼의 각 변수를 확인해야한다는 말입니까?
— Paul Ruane 2010 년

소스를 살펴본 결과 홈이 자동으로 채워지지 않은 것 같습니다. (현재) 홈 디렉토리를 얻기위한 플랫폼에 구애받지 않는 기능이없는 것 같습니다.
— Paul Ruane 2011 년

@PaulRuane 플랫폼은 서로 다른 변수를 사용하므로 OS를 무시하고 두 변수를 모두 확인한 다음 채워진 변수를 사용하십시오. 둘 다 정의되어 있으면 HOME아마도 cygwin에서 실행 중임을 의미하기 때문에을 사용합니다.
— 제레미 W. 셔먼

당신은해야 하지 사용 USERPROFILE또는 HOMEPATH대부분의 경우에 Windows에서. DEVS 그를 사용하는 대부분의 경우, 그들이 무엇을 해야 사용하는 것은 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의 대답과 같은 접근 방식입니다.)
— 폴 Ruane

이것은 대부분의 경우 올바른 솔루션이 아닙니다 . 다른 답변에 대한 의견 만 TL을 참조; DR이 그 것이다 APPDATA나 LOCALAPPDATA하지, 거의 항상 올바른 선택입니다 USERPROFILEWindows에서.
— Micah Zoltu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.