Есть ли портативный способ получить текущее имя пользователя в Python?


598

Существует ли портативный способ получить имя пользователя текущего пользователя в 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
Мэтт Брузек,

17
@MattBruzek Это был пункт OP там. Он представлял, как можно вызвать такую ​​функцию, если она существует.
тыкай

Ответы:


836

Посмотрите на модуль getpass

import getpass
getpass.getuser()
'kostya'

Доступность: Unix, Windows


ps На комментарий ниже " эта функция просматривает значения различных переменных среды для определения имени пользователя. Поэтому на эту функцию не следует полагаться в целях контроля доступа (или, возможно, в любых других целях, поскольку она позволяет любому пользователю выдавать себя за любое другое ). "


100
Похоже, что эта функция просматривает значения различных переменных среды, чтобы определить имя пользователя. Поэтому на эту функцию не следует полагаться для целей контроля доступа (или, возможно, для любых других целей, поскольку она позволяет любому пользователю выдавать себя за любого другого).
Грег Хьюгилл

25
В getpass.getuser () нет ничего плохого, поскольку он не претендует на аутентификацию пользователя. Цель этой функции - определить, кем является пользователь, не спрашивая его напрямую.
Уокер Хейл IV

7
Это не работает, если вы сделали su. $ echo $ USER hithwen $ su julia Пароль: $ echo $ USER julia $ python >>> import getpass >>> getpass.getuser () 'hithwen'
hithwen

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

16
И я согласен с @GregHewgill в целях контроля доступа, но совершенно не согласен с «любыми другими целями» - это все равно что сказать «Не используйте $ USER в сценарии оболочки». Отличная особенность контроля доступа, но есть множество других применений, которые не связаны с аутентификацией.
Невел

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
Это правильный путь, если вам нужно получить имя пользователя как во время входа, так и без него.
Деррик Чжан,

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

1
Этот метод в unix-подобных системах намного превосходит ответ Константина Тензина, потому что он sudoправильно обрабатывает случай. (Я знаю, что OP не просил Unix-подобные системы.)
Halloleo

86

Вы также можете использовать:

 os.getlogin()

29
В linux getlogin () возвращает имя «пользователя, вошедшего в систему на управляющем терминале процесса». Поэтому происходит сбой, когда нет управляющего терминала, например, в приложении mod_python.
Вебьорн Лёса

23
Недоступно для Windows
Уокер Хейл 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.getlogin () 'jrb'
Наиб

5
Он доступен только в Windows для Python 3.x.
Цитрак

71

Вы, вероятно, можете использовать:

os.environ.get('USERNAME')

или

os.environ.get('USER')

Но это не будет безопасным, потому что переменные среды могут быть изменены.


18
os.getenv(...)не рекомендуется в пользу os.environ[...].
Майк Грэм,

11
Разве это не USERNAME вместо USERNAME?
Карл Бартель,

7
@MikeGraham os.getenvне кажется устаревшим ..?
2012 года

4
Да, именно USER vs USERNAME - это то, что не является переносимым, поэтому не дает правильного ответа.
Питер М

2
USERNAME для Windows, USER для Linux
Сабрина

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
Этот ответ, по крайней мере, так же полезен, как и (бесполезный) 25-голосовый голос только для Unix.
Том Б,

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
Сабрина

К сожалению, если вы установите переменную 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]           

Вывод:

Окна:

Дом пользователя Dir: C: \ Users \ myuser

имя пользователя: myuser

Linux:

Дом пользователя Dir: / root

имя пользователя: root

Нет необходимости устанавливать какие-либо модули или расширения.


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

Установка переменной 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

К; тогда используйте подпроцесс ...
jeez

2 замечания. command.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/en/python/plx

Применение:

import plx

username = plx.get_username()

(для Windows требуется расширение win32)


4

Используя только стандартные библиотеки Python:

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 также является стандартным lib
jodag

у меня не работает в win10, python3.7.4. я думаю, что это жалоба на то, что «USER» не найден в переменных окружения. Я думаю, что getpass - лучший выбор.
Рика

3

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

Я написал небольшой модуль, который может сделать это прямо из Python, getuser.py . Применение:

import getuser
print(getuser.lookup_username())

Он работает как в Windows, так и в * nix (последний использует pwdмодуль, как описано в других ответах).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.