Apakah ada cara portabel untuk mendapatkan nama pengguna saat ini di Python?

598

Apakah ada cara portabel untuk mendapatkan nama pengguna pengguna saat ini dalam Python (yaitu, yang bekerja di Linux dan Windows, setidaknya). Ini akan bekerja seperti os.getuid:

>>> os.getuid()
42
>>> os.getusername()
'slartibartfast'

Saya mencari di sekitar dan terkejut tidak menemukan jawaban yang pasti (meskipun mungkin saya hanya googling buruk). The pwd modul menyediakan cara yang relatif mudah untuk mencapai di bawah ini, mengatakan, Linux, tetapi tidak hadir pada Windows. Beberapa hasil pencarian menyarankan agar mendapatkan nama pengguna di Windows dapat menjadi rumit dalam keadaan tertentu (misalnya, berjalan sebagai layanan Windows), meskipun saya belum memverifikasi itu.

Jacob Gabrielson
sumber
Itu tidak berfungsi di kotak Linux saya!
Riccardo
5
import pwd, os; print pwd.getpwuid(os.getuid()).pw_gecosatauimport pwd, os; print pwd.getpwuid(os.getuid()).pw_name
chown
getusername () bukan metode yang valid dalam modul os Python: docs.python.org/2.7/library/os.html
Matt Bruzek
17
@MattBruzek Itulah poin OP di sana. Dia membayangkan bagaimana fungsi seperti itu bisa disebut jika ada.
colek

Jawaban:

836

Lihatlah modul getpass

import getpass
getpass.getuser()
'kostya'

Ketersediaan: Unix, Windows


ps Per komentar di bawah " fungsi ini melihat nilai-nilai berbagai variabel lingkungan untuk menentukan nama pengguna. Oleh karena itu, fungsi ini tidak boleh diandalkan untuk tujuan kontrol akses (atau mungkin tujuan lain, karena memungkinkan setiap pengguna untuk menyamar sebagai yang lain). ). "

Konstantin Tenzin
sumber
100
Tampaknya fungsi ini melihat nilai-nilai berbagai variabel lingkungan untuk menentukan nama pengguna. Oleh karena itu, fungsi ini tidak boleh diandalkan untuk tujuan kontrol akses (atau mungkin tujuan lain, karena memungkinkan pengguna untuk menyamar sebagai yang lain).
Greg Hewgill
25
Tidak ada yang salah dengan getpass.getuser (), karena tidak mengklaim untuk mengotentikasi pengguna. Tujuan dari fungsi ini adalah untuk menentukan siapa pengguna yang diklaim tanpa meminta pengguna secara langsung.
Walker Hale IV
7
Itu tidak berfungsi jika Anda telah melakukan su. $ echo $ USER hithwen $ su julia Kata sandi: $ echo $ USER julia $ python >>> impor getpass >>> getpass.getuser () 'hithwen'
hithwen
6
@GregHewgill memunculkan poin yang sangat bagus, tetapi memang, mengetahui nama pengguna dengan cara sederhana yang tidak diautentikasi seperti ini memang memiliki beberapa aplikasi. Kasus penggunaan saya saat ini: menandai beberapa sumber daya pengujian bersama dengan nama pengguna untuk pembersihan mudah nanti. (Jadi lebih mudah untuk mencari tahu kekacauan siapa yang.)
driftcatcher
16
Dan saya setuju dengan @GregHewgill untuk tujuan kontrol akses, tetapi sama sekali tidak setuju dengan 'tujuan lain' - itu seperti mengatakan "Jangan gunakan $ USER dalam skrip shell". Poin bagus tentang kontrol akses tetapi ada banyak kegunaan lain yang tidak melibatkan auth.
nevelis
119

Anda bertaruh yang terbaik adalah menggabungkan os.getuid()dengan pwd.getpwuid():

import os
import pwd

def get_username():
    return pwd.getpwuid( os.getuid() )[ 0 ]

Lihat dokumen pwd untuk lebih jelasnya:

http://docs.python.org/library/pwd.html

Liam Chasteen
sumber
51
Atau (sedikit lebih bagus untuk membaca): pwd.getpwuid(os.getuid()).pw_name.
Brian M. Hunt
6
Apa fungsinya di Windows? Mungkin orang bisa mencoba ini, dan jika gagal, kembali ke metode 'getpass / env var' yang jelek.
Jonathan Hartley
2
Ini adalah cara yang benar jika Anda perlu mendapatkan nama pengguna dengan dan tanpa masuk.
Derrick Zhang
5
@ JonathanHartley:ImportError: No module named pwd
Justin
1
Metode ini pada sistem seperti unix jauh lebih unggul daripada jawaban Konstantin Tenzin, karena menangani sudokasus dengan benar. (Saya sadar OP tidak melakukannya; saya tidak meminta ssytem seperti-unix.)
halloleo
86

Anda juga bisa menggunakan:

 os.getlogin()
Marcin Augustyniak
sumber
29
Di linux, getlogin () mengembalikan nama "pengguna yang masuk pada terminal pengendali proses." Karena itu gagal ketika tidak ada terminal pengendali, misalnya, dalam aplikasi mod_python.
Vebjorn Ljosa
23
Tidak tersedia untuk Windows
Walker Hale IV
3
Jika Anda menggunakan su, maka ini tidak akan mengembalikan pengguna saat ini, tetapi pengguna yang semula masuk.
Trevor Allred
4
tidak bekerja pada windows ... Python 3.4.1 (v3.4.1: c0e311e010fc, 18 Mei 2014, 10:38:22) [MSC v.1600 32 bit (Intel)] pada win32 Ketik "help", "hak cipta", "kredit" atau "lisensi" untuk informasi lebih lanjut. >>> impor os; os.getlogin () 'jrb'
Naib
5
Ini hanya tersedia di Windows untuk Python 3.x.
Zitrax
71

Anda mungkin dapat menggunakan:

os.environ.get('USERNAME')

atau

os.environ.get('USER')

Tapi itu tidak akan aman karena variabel lingkungan dapat diubah.

Nadia Alramli
sumber
18
os.getenv(...)tidak digunakan lagi os.environ[...].
Mike Graham
11
Bukankah seharusnya USER, bukan USERNAME?
Karl Bartel
7
@MikeGraham os.getenvsepertinya tidak ditinggalkan ..?
dbr
4
Ya, tepatnya USER vs USERNAME adalah persis apa yang tidak portabel, sehingga tidak memberikan jawaban yang benar.
Peter M
2
USERNAME untuk Windows, USER untuk Linux
Sabrina
22

Ini mungkin berhasil. Saya tidak tahu bagaimana mereka berperilaku ketika menjalankan sebagai layanan. Mereka tidak portabel, tapi untuk itulah os.namedan ifpernyataan.

win32api.GetUserName()

win32api.GetUserNameEx(...) 

Lihat: http://timgolden.me.uk/python/win32_how_do_i/get-the-owner-of-a-file.html

Adam
sumber
30
Jawaban ini setidaknya sama bermanfaatnya dengan jawaban 25-suara yang tidak digunakan (tidak berguna).
Tom B
3
> "Setidaknya sama bermanfaatnya" Setuju. Agaknya jawaban yang benar adalah kombinasi keduanya.
Jonathan Hartley
Jika Anda terjebak pada python 2 di Windows, ini adalah satu-satunya cara aman untuk melakukannya. Semua cara lain bisa diakali dengan menjalankan SET USERNAME=FAKEsebelum perintah python Anda
CodeKid
21

Jika Anda memerlukan ini untuk mendapatkan dir home user, di bawah ini dapat dianggap sebagai portable (setidaknya win32 dan linux), bagian dari perpustakaan standar.

>>> os.path.expanduser('~')
'C:\\Documents and Settings\\johnsmith'

Anda juga dapat menguraikan string tersebut untuk mendapatkan hanya komponen jalur terakhir (mis. Nama pengguna).

Lihat: os.path.expanduser

HezniK
sumber
9
Direktori rumah seseorang tidak selalu mencerminkan nama pengguna mereka.
dreamlax
Ini berfungsi di Linux & Windows
Sabrina
Sayangnya, jika Anda mengatur variabel HOME di Windows, ini akan mengembalikan nilai itu.
GLRoman
15

Bagi saya menggunakan osmodul terlihat yang terbaik untuk portabilitas: Berfungsi paling baik di Linux dan Windows.

import os

# Gives user's home directory
userhome = os.path.expanduser('~')          

print "User's home Dir: " + userhome

# Gives username by splitting path based on OS
print "username: " + os.path.split(userhome)[-1]           

Keluaran:

Windows:

Rumah pengguna Dir: C: \ Users \ myuser

nama pengguna: pengguna saya

Linux:

Dir home home Pengguna: / root

nama pengguna: root

Tidak perlu memasang modul atau ekstensi apa pun.


sumber
16
Solusi ini cerdas, tetapi membuat beberapa asumsi yang tidak selalu benar. Tidak ada kendala yang mengharuskan nama pengguna muncul di jalur homedir di Linux. Kebetulan sebagian besar waktu, tetapi sysadmin dapat mengatur homedir pengguna untuk apa pun yang mereka inginkan.
Joe Holloway
Mengatur variabel HOME mengalahkan ini.
GLRoman
11

Gabungan pwddan getpasspendekatan, berdasarkan jawaban lain:

try:
  import pwd
except ImportError:
  import getpass
  pwd = None

def current_user():
  if pwd:
    return pwd.getpwuid(os.geteuid()).pw_name
  else:
    return getpass.getuser()
techtonik anatoly
sumber
9

Untuk UNIX, setidaknya, ini berfungsi ...

import commands
username = commands.getoutput("echo $(whoami)")
print username

sunting: Saya baru saja mencarinya dan ini berfungsi pada Windows dan UNIX:

import commands
username = commands.getoutput("whoami")

Pada UNIX ia mengembalikan nama pengguna Anda, tetapi pada Windows, ia mengembalikan grup pengguna Anda, slash, nama pengguna Anda.

-

YAITU

Pengembalian UNIX: "username"

Windows mengembalikan: "domain / nama pengguna"

-

Ini menarik, tetapi mungkin tidak ideal kecuali Anda melakukan sesuatu di terminal ... dalam hal ini Anda mungkin akan menggunakan os.systemuntuk memulai. Sebagai contoh, beberapa saat yang lalu saya perlu menambahkan pengguna saya ke grup, jadi saya melakukannya (ini di Linux, ingat)

import os
os.system("sudo usermod -aG \"group_name\" $(whoami)")
print "You have been added to \"group_name\"! Please log out for this to take effect"

Saya merasa itu lebih mudah dibaca dan Anda tidak perlu mengimpor pwd atau getpass.

Saya juga merasa memiliki "domain / pengguna" dapat membantu dalam aplikasi tertentu di Windows.

dylnmc
sumber
1
WIndows kembali domain/user tidakgroup/user
RealHowTo
4
Modul perintah tidak berfungsi di Windows. Ini adalah modul khusus UNIX (lihat docs.python.org/2/library/commands.html ). Sekarang sudah usang dan sebagai gantinya dianjurkan. user = subprocess.check_output("whoami").replace("\r\n", "")
ConnectedSystems
k; kemudian gunakan subproses ... ya ampun
dylnmc
2 komentar. commands.whoami bekerja dengan baik, bahkan dalam konteks layanan yang berjalan di bawah nama pengguna yang berbeda. yaitu dengan chpst -u nobody python ./manage.py celerycam --pidfile=/var/run/celerycam/celerycam.pid saya tidak punya siapa - siapa . kedua, user = subprocess.check_output("whoami").strip() lebih portabel daripada mengganti linefeeds di atas. commandsvs subprocesstampaknya nitpicky tetapi perintah hilang dari python 3.
JL Peyret
5

Saya menulis modul plx beberapa waktu lalu untuk mendapatkan nama pengguna dengan cara portabel di Unix dan Windows (antara lain): http://www.decalage.info/en/python/plx

Pemakaian:

import plx

username = plx.get_username()

(membutuhkan ekstensi win32 di Windows)

decalage
sumber
4

Hanya menggunakan lib python standar:

from os import environ,getcwd
getUser = lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"]
user = getUser()

Bekerja di Windows, Mac atau Linux

Atau, Anda dapat menghapus satu baris dengan permintaan langsung:

from os import environ,getcwd
user = (lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"])()
ThisGuyCantEven
sumber
1
getpass juga merupakan lib
jodag
tidak bekerja untuk saya di win10, python3.7.4. itu mengeluh tentang 'PENGGUNA' tidak ditemukan dalam variabel envirnment kurasa. Saya kira getpass adalah pilihan yang lebih baik.
Rika
3

Anda bisa mendapatkan nama pengguna saat ini di Windows dengan pergi melalui API Windows, meskipun agak sulit untuk dipanggil melalui ctypes FFI ( GetCurrentProcessOpenProcessTokenGetTokenInformationLookupAccountSid ).

Saya menulis sebuah modul kecil yang dapat melakukan ini langsung dari Python, getuser.py . Pemakaian:

import getuser
print(getuser.lookup_username())

Ini bekerja pada Windows dan * nix (yang terakhir menggunakan pwdmodul seperti yang dijelaskan dalam jawaban lain).

Michael Kropat
sumber