Jak znaleźć katalog domowy prawdziwego użytkownika za pomocą Pythona?

81

Widzę, że jeśli zmienimy zmienną środowiskową HOME (linux) lub USERPROFILE (windows) i uruchomimy skrypt w języku Python, zwróci on nową wartość jako użytkownik domowy, gdy próbowałem, os.environ ['HOME'] os.exp

Czy istnieje sposób, aby znaleźć katalog osobisty rzeczywistego użytkownika bez polegania na zmiennej środowiskowej?

edit:
Oto sposób na znalezienie userhome w systemie Windows, czytając w rejestrze, http://mail.python.org/pipermail/python-win32/2008-J January/006677.html

edycja:
jeden ze sposobów znajdowania domu systemu Windows za pomocą pywin32,

from win32com.shell import shell,shellcon
home = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, None, 0)
asdfg
źródło
Możesz sprawdzić polecenie unixa (skrót): ~userPrzenosi cię do katalogu domowego bieżącego użytkownika. W oknach nie mam pojęcia.
mAm
Powinien być oznaczony jako duplikat How to get the home directory in Python? ponieważ zaakceptowana odpowiedź na to pytanie działa w Pythonie 3, a na to pytanie nie.
Dour High Arch

Odpowiedzi:

96

Myślę, że os.path.expanduser(path)mogłoby być pomocne.

W systemach Unix i Windows zwraca argument z początkowym składnikiem katalogu domowego tego użytkownika ~ lub ~userprzez niego zastąpiony.

W systemie Unix inicjał ~jest zastępowany zmienną środowiskową HOME, jeśli jest ustawiona; w przeciwnym razie katalog domowy bieżącego użytkownika jest przeszukiwany w katalogu haseł przez wbudowany moduł pwd. Inicjał ~userjest wyszukiwany bezpośrednio w katalogu haseł .

W systemie Windows zostaną użyte opcje HOME i USERPROFILE, jeśli są ustawione, w przeciwnym razie zostanie użyta kombinacja HOMEPATH i HOMEDRIVE . Inicjalizacja ~userjest obsługiwana przez usunięcie ostatniego składnika katalogu z utworzonej ścieżki użytkownika wyprowadzonej powyżej .

Jeśli rozwinięcie nie powiedzie się lub jeśli ścieżka nie zaczyna się od tyldy, ścieżka jest zwracana bez zmian.

Możesz więc po prostu zrobić:

os.path.expanduser('~user')
Felix Kling
źródło
3
To prawda, ale zmiana zmiennej środowiskowej, jak w pytaniu, "oszuka" również tę metodę. Nie potrafię powiedzieć, dlaczego ktoś miałby to robić. :)
Jakob Borg
1
@calmh: Tak, zmieniłem go na taki, '~user'który powinien działać na Linuksie i Windowsie (tutaj nie jestem pewien w 100%, ponieważ nie mam Windowsa do testowania;)).
Felix Kling
1
To działa w systemie Linux, ale nie w systemie Windows. W systemie Windows po prostu łączy „C: \ Documents and settings” z podaną nazwą użytkownika.
asdfg
Nie rozwiązuje to problemu błędnej zmiennej „HOME”. Zobacz na przykład cadence.com/Community/forums/t/17969.aspx
endolith
1
@asdfg: Wydaje mi się, że działało poprawnie. Ale ja też myślałem, że się nie udało, gdy próbowałem po raz pierwszy, ponieważ na początku przekazywałem dosłowny ciąg „~ user” (który naprawdę musi być czymś dosłownym, takim jak „~ Bob”), zamiast aktualny użytkownik).
Jon Coombs
17

Myślę, że os.path.expanduser(path)to najlepsza odpowiedź na twoje pytanie, ale istnieje alternatywa, o której warto wspomnieć w świecie Uniksa: pwdpakiet. na przykład

import os, pwd

pwd.getpwuid(os.getuid()).pw_dir
Brian M. Hunt
źródło
1
Jest to przydatne, gdy chcesz mieć katalog domowy użytkownika, ale zmienna środowiskowa HOME jest niepoprawnie ustawiona. Jak zauważył autor, nie jest niezależny od platformy, ale raczej dla UNIX, a nie Windows.
user1071847
1
Jest to lepsze niż poleganie na zmiennej HOME env, która może, ale nie musi, zostać zachowana w wywołaniach sudo. Na przykład HOME env. zmienna jest ustawiona na użytkownika docelowego w Debianie 8 ('sudo' działa jak 'sudo -H'), ale jest zachowywana w Ubuntu 16 ('sudo' działa jak 'sudo -E')
Andrei Korostelev
17
from pathlib import *

str(Path.home())

działa w Pythonie 3.5 i nowszych. Path.home()zwraca Pathobiekt udostępniający API, które uważam za bardzo przydatne.

Julius Kunze
źródło
1
Wewnętrznie pathlibnadal opiera się na zmiennych środowiskowych, więc nie odpowiada to na twoje konkretne pytanie. Ponieważ wszystkie pytania bardziej ogólne zostały oznaczone jako duplikaty i odnoszą się do nich tutaj, może to być najlepsze miejsce na tę odpowiedź.
Julius Kunze
pathlib to teraz moja biblioteka do obsługi ścieżek! Nie wiedziałem o .home (). Będę musiał ponownie odwiedzić dokumentację, aby przejrzeć całą dobroć. Twoje zdrowie!
PlacidLush
5

home_folder = os.getenv('HOME')

Powinno to działać również w systemie Windows i Mac OS, działa dobrze w systemie Linux.

Panie Zeus
źródło
1
przynajmniej to nie działa na zmiennej win10 coz ma nazwę HOMEPATH
Reishin
@Reishin to nie do końca prawda, właśnie to przetestowałem i działa na Windows 10 Pro. Naprawdę nie sądzę, żeby mogli sobie pozwolić na zmianę nazwy zmiennej środowiskowej dla kaprysu, biorąc pod uwagę ilość oprogramowania, które spodziewa się znaleźć ją pod tą nazwą.
sm
@sm, spróbuj znaleźć tutaj zmienną „HOME” technet.microsoft.com/en-us/library/cc749104(v=ws.10).aspx . Jeśli masz zmienną niestandardową, nie oznacza to, że mają ją wszyscy ppl. Najczęściej, takie jak mingw, cygwin, git shell itp. ... ustawiając to za Ciebie. Ale jeśli uruchomisz cmd.exe,
byłbyś
4

Dla Windowsa;

import os
homepath = os.path.expanduser(os.getenv('USERPROFILE'))

da ci uchwyt do katalogu domowego bieżącego użytkownika i

filepath = os.path.expanduser(os.getenv('USERPROFILE'))+'\\Documents\\myfile.txt'

da ci uchwyt do poniższego pliku;

C:\Users\urUserName\Documents\myfile.txt
khawarizmi
źródło
3

W rzeczywistości zmiana zmiennej środowiskowej wskazuje, że dom musi zostać zmieniony. Więc każdy program / skrypt powinien mieć nowy dom w kontekście; również konsekwencje zależą od osoby, która to zmieniła. Nadal bym się trzymał home = os.getenv('USERPROFILE') or os.getenv('HOME')

co dokładnie jest wymagane?

posiadacz pierścienia
źródło
5
Z wyjątkiem Cygwin, w którym to przypadku oba są zwykle zdefiniowane i wiele razy różne.
amfetamachine
3

Zdaję sobie sprawę, że to stare pytanie, na które udzielono odpowiedzi, ale pomyślałem, że dodam swoje dwa centy. Przyjęta odpowiedź nie działała dla mnie. Musiałem znaleźć katalog użytkownika i chciałem, aby działał zi bez sudo. W Linuksie mój katalog użytkownika to „/ home / someuser”, ale mój katalog główny to „/ root /”. Jednak na moim Macu katalog użytkownika to „/ Users / someuser”. Oto, co ostatecznie zrobiłem:

_USERNAME = os.getenv("SUDO_USER") or os.getenv("USER") 
_HOME = os.path.expanduser('~'+_USERNAME)

Działało to zarówno z, jak i bez sudona komputerach Mac i Linux.

Julien Spronck
źródło
Wiem, że powiedziałeś Mac i Linux, ale w Windows _USERNAMEbyło None. Dla przyszłych czytelników.
Thomas Fauskanger
z pathlib import Path; Path.home (). As_posix () # działa również w systemie Windows. Zasadniczo tak samo jak metoda Sproncka, może być bardziej naturalny.
mikey
Czy byłoby ulepszeniem, aby działał z oknami or ""?
PascalVKooten
0

W systemie Linux i innych UNIXoidach zawsze możesz zajrzeć /etc/passwd. Katalog domowy to szóste pole rozdzielone dwukropkami. Nie mam jednak pojęcia, jak to zrobić lepiej niż zmienna środowiskowa w systemie Windows. Pojawi się wywołanie systemowe, ale jeśli jest dostępne z Pythona, ...

Jakob Borg
źródło
1
Ale to byłby tylko Unix (Linux), prawda?
okaziciel pierścienia
1
@ring - tak. Dodano tekst w tej sprawie.
Jakob Borg
-1

pobierz (przetłumaczone) nazwy folderów użytkowników w systemie Linux:

from gi.repository import GLib

docs = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS)
desktop = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP)
pics = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)
videos = GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)
music = GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)
downloads = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
public = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PUBLIC_SHARE)
templates = GLib.get_user_special_dir(GLib.USER_DIRECTORY_TEMPLATES)

print(docs)
print(desktop)
print(pics)
print(videos)
print(music)
print(downloads)
print(public)
print(templates)
Axel Schneider
źródło
przetłumaczone jak?
gerrit
Przetłumaczone na język systemu operacyjnego.
Axel Schneider