Чи є портативний спосіб отримати поточне ім'я користувача в Python?


597

Чи є портативний спосіб отримати ім'я користувача поточного користувача в Python (тобто, що працює принаймні як під Linux, так і з Windows). Це буде працювати так os.getuid:

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

Я погуляв навколо і здивувався, що не знайшов остаточної відповіді (хоча, можливо, я просто погано гуглю). Модуль pwd забезпечує порівняно простий спосіб досягти цього, скажімо, під Linux, але його немає в Windows. Деякі з результатів пошуку припускають, що отримати ім'я користувача під Windows може бути складним за певних обставин (наприклад, запуск служби Windows), хоча я цього ще не підтвердив.


Це не працює на моєму Linux-коробці!
Ріккардо

5
import pwd, os; print pwd.getpwuid(os.getuid()).pw_gecosабоimport pwd, os; print pwd.getpwuid(os.getuid()).pw_name
човен

getusername () недійсний метод у модулі os Python: docs.python.org/2.7/library/os.html
Matt Bruzek

17
@MattBruzek Це був пункт OP. Він уявляв, як можна назвати таку функцію, якби вона існувала.
ткнути

Відповіді:


836

Подивіться на модуль getpass

import getpass
getpass.getuser()
'kostya'

Наявність: Unix, Windows


ps За коментарем нижче " Ця функція розглядає значення різних змінних середовища для визначення імені користувача. Тому на цю функцію не слід покладатися з метою контролю доступу (або, можливо, будь-якої іншої цілі, оскільки вона дозволяє будь-якому користувачеві представляти себе будь-яким іншим ) ".


100
Здається, що ця функція розглядає значення різних змінних середовища для визначення імені користувача. Тому на цю функцію не слід покладатися з метою контролю доступу (або, можливо, будь-якої іншої мети, оскільки вона дозволяє будь-якому користувачеві себе представляти будь-якому іншому).
Грег Х'югілл

25
З getpass.getuser () немає нічого поганого, оскільки він не претендує на автентифікацію користувача. Мета функції - визначити, на кого претендує користувач, не запитуючи його безпосередньо.
Уокер Хейл IV

7
Це не спрацює, якщо ви зробили су. $ echo $ USER hithwen $ su julia Пароль: $ echo $ USER julia $ python >>> імпорт getpass >>> getpass.getuser () 'hithwen'
hithwen

6
@GregHewgill викликає дуже хороший момент, але, дійсно, пошук імені користувача простим несанкціонованим способом, як це має деякі програми. Мій поточний випадок використання: позначення деяких спільних тестових ресурсів з іменем користувача для легкої очищення пізніше (Так простіше зрозуміти, чий безлад є чий.)
driftcatcher

16
І я погоджуюся з @GregHewgill з метою контролю доступу, але повністю не погоджуюся з "будь-якою іншою метою" - це як сказати "Не використовуйте $ USER у скрипті оболонки". Відмінний момент щодо контролю доступу, але є багато інших застосувань, які не передбачають автентичності.
nevelis

119

Найкраще зробити ставку на поєднання os.getuid()з pwd.getpwuid():

import os
import pwd

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

Детальнішу інформацію див. У документах pwd:

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


51
Як альтернативи (трохи краще читати) pwd.getpwuid(os.getuid()).pw_name.
Брайан М. Хант

6
Що це робиться в Windows? Можливо, хтось міг би спробувати це, і якщо це не вдасться, повернутися до шалених методів "getpass / env var".
Джонатан Хартлі

2
Це правильний спосіб, якщо вам потрібно отримати ім’я користувача як із входом, так і без нього.
Derrick Zhang,

5
@JonathanHartley:ImportError: No module named pwd
Джастін

1
Цей метод застосовується в системах, схожих на unix, набагато перевершує відповідь Костянтина Тензіна, оскільки він обробляє sudoсправу правильно. (Мені відомо, що ОП не робив; не вимагав уніксаподібних систем.)
halloleo

86

Ви також можете використовувати:

 os.getlogin()

29
У Linux Linux getlogin () повертає ім'я "користувача, який увійшов у керуючий термінал процесу." Тому він виходить з ладу, коли немає керуючого терміналу, наприклад, у програмі mod_python.
Вебйорн Льоса

23
Не доступно для Windows
Walker Hale IV

3
Якщо ви використовували su, це не поверне поточного користувача, але спочатку ввійшов користувач.
Тревор Алред

4
працює на Windows ... Python 3.4.1 (v3.4.1: c0e311e010fc, 18 травня 2014, 10:38:22) [MSC v.1600 32 біт (Intel)] у win32 Введіть "допомогу", "авторські права", "кредити" або "ліцензія" для отримання додаткової інформації. >>> імпортувати os; os.getlogin () 'JRB'
наиб

5
Він доступний лише в Windows для Python 3.x.
Zitrax

71

Можливо, ви можете використовувати:

os.environ.get('USERNAME')

або

os.environ.get('USER')

Але це не буде безпечним, оскільки змінні середовища можуть бути змінені.


18
os.getenv(...)застаріло на користь os.environ[...].
Майк Грехем

11
Чи не повинен це бути USER замість USERNAME?
Карл Бартель

7
@MikeGraham os.getenvне здається застарілим ..?
грудня 12

4
Так, саме USER vs USERNAME - це саме те, що не є портативним, тому це не дає правильної відповіді.
Пітер М

2
USERNAME призначений для Windows, USER призначений для Linux
Sabrina

22

Вони можуть спрацювати. Я не знаю, як вони поводяться під час роботи як служби. Вони не портативні, але саме для цього os.nameі ifтвердження.

win32api.GetUserName()

win32api.GetUserNameEx(...) 

Дивіться: http://timgolden.me.uk/python/win32_how_do_i/get-the-owner-of-a-file.html


30
Ця відповідь є принаймні такою ж корисною, як і (непотрібна) відповідь на підтримку єдиного Unix, що має 25 голосів.
Том Б

3
> "Принаймні як корисно" Домовлено. Імовірно, правильною відповіддю є поєднання двох.
Джонатан Хартлі

Якщо ви застрягли на python 2 в Windows, це єдиний безпечний спосіб зробити це. Усі інші способи можна випробувати, запустивши SET USERNAME=FAKEперед вашою командою python
CodeKid

21

Якщо вам це потрібно для отримання домашнього режиму користувача, нижче можна вважати портативним (win32 та Linux як мінімум), частиною стандартної бібліотеки.

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

Також ви можете проаналізувати такий рядок, щоб отримати лише останній компонент шляху (тобто ім'я користувача).

Див.: Os.path.expanduser


9
Хтось домашній каталог не завжди відображає їх ім’я користувача.
dreamlax

Це працює і в Linux, і в Windows
Sabrina

На жаль, якщо встановити змінну HOME у Windows, це поверне їй це значення.
GLRoman

15

Для мене використання osмодуля виглядає найкраще для портативності: найкраще працює в Linux і 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]           

Вихід:

Windows:

Головна сторінка користувача Dir: C: \ Users \ myuser

ім'я користувача: myuser

Linux:

Головна сторінка користувача Dir: / root

ім'я користувача: root

Не потрібно встановлювати будь-які модулі чи розширення.


16
Це рішення розумне, але робить деякі припущення, які не завжди відповідають дійсності. Немає обмежень, які вимагають, щоб ім'я користувача з'являлося в ході hiredir в Linux. Просто так трапляється у більшості випадків, але sysadmin може встановити homedir користувача на все, що вони хочуть.
Джо Холлоуей

Встановлення змінної HOME перемагає це.
GLRoman

11

Комбінований pwdта getpassпідхід, заснований на інших відповідях:

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

9

Принаймні, для UNIX це працює ...

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

редагувати: я щойно переглянув це, і це працює в Windows та UNIX:

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

У UNIX він повертає ваше ім'я користувача, але в Windows він повертає групу вашого користувача, косу рису, ваше ім'я користувача.

-

IE

UNIX повертає: "ім'я користувача"

Windows повертає: "домен / ім'я користувача"

-

Це цікаво, але, мабуть, не ідеально, якщо все-таки ви щось не робите в терміналі ... в такому випадку ви, напевно, os.systemпочали використовувати. Наприклад, деякий час тому мені потрібно було додати свого користувача до групи, і я це зробив (це в Linux, врахуйте)

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"

Я відчуваю, що це легше читати, і вам не потрібно імпортувати pwd або getpass.

Я також вважаю, що наявність домену / користувача може бути корисною для певних програм у Windows.


1
WIndows domain/user не повертаєтьсяgroup/user
RealHowTo

4
Модуль команд не працює в Windows. Це специфічний модуль UNIX (див. Docs.python.org/2/library/commands.html ). Зараз це застаріло, а замість нього рекомендується підпроцес. user = subprocess.check_output("whoami").replace("\r\n", "")
ConnectedSystems

k; потім використовуйте підпроцес ... jeez
dylnmc

2 зауваження. commandnds.whoami зробив чудово навіть у контексті служби, що працює під іншим іменем користувача. тобто з chpst -u nobody python ./manage.py celerycam --pidfile=/var/run/celerycam/celerycam.pid мене нікого немає . по-друге, user = subprocess.check_output("whoami").strip() є більш портативним, ніж замінити подачі ліній вище. commandsvs subprocessздається ниткоподібним, але команд відсутнє в python 3.
JL Peyret

5

Я писав модуль plx деякий час тому, щоб отримати ім’я користувача портативно на Unix та Windows (серед іншого): http://www.decalage.info/uk/python/plx

Використання:

import plx

username = plx.get_username()

(для Windows потрібні розширення win32)


4

Використовуючи лише стандартні ліфти пітона:

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

Працює в Windows, Mac або Linux

Можна також видалити один рядок негайним викликом:

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

1
getpass - це також стандартний
ліб

не працює для мене в win10, python3.7.4. його скарги на те, що "USER" не знаходяться в змінних навколишнього середовища, я думаю. Я думаю, що getpass - кращий вибір у будь-якому випадку.
Рика

3

Ви можете отримати поточне ім'я користувача в Windows, перейшовши через API Windows, хоча викликати через типи FFI ( GetCurrentProcessOpenProcessTokenGetTokenInformationLookupAccountSid ) дещо громіздко .

Я написав невеликий модуль, який може це зробити прямо з Python, getuser.py . Використання:

import getuser
print(getuser.lookup_username())

Він працює як у Windows, так і * nix (останній використовує pwdмодуль, як описано в інших відповідях).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.