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

HezniK
источник
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.

dylnmc
источник
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)

decalage
источник
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"])()
ThisGuyCantEven
источник
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модуль, как описано в других ответах).

Майкл Кропат
источник