Existe uma maneira portátil de obter o nome de usuário atual no Python?

598

Existe uma maneira portátil de obter o nome de usuário do usuário atual em Python (ou seja, um que funcione no Linux e no Windows, pelo menos). Funcionaria como os.getuid:

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

Eu pesquisei e fiquei surpreso por não encontrar uma resposta definitiva (embora talvez eu estivesse apenas pesquisando mal). O módulo pwd fornece uma maneira relativamente fácil de conseguir isso no Linux, por exemplo, mas não está presente no Windows. Alguns dos resultados da pesquisa sugeriram que a obtenção do nome de usuário no Windows pode ser complicada em determinadas circunstâncias (por exemplo, executando como um serviço do Windows), embora eu não tenha verificado isso.

Jacob Gabrielson
fonte
Não funciona na minha caixa Linux!
Riccardo
5
import pwd, os; print pwd.getpwuid(os.getuid()).pw_gecosouimport pwd, os; print pwd.getpwuid(os.getuid()).pw_name
chown 01/03
GetUserName () não é um método válido no módulo Python os: docs.python.org/2.7/library/os.html
Matt Bruzek
17
@MattBruzek Esse era o ponto da OP lá. Ele estava imaginando como essa função poderia ser chamada se existisse.
cutuca

Respostas:

836

Veja o módulo getpass

import getpass
getpass.getuser()
'kostya'

Disponibilidade: Unix, Windows


ps Por comentário abaixo ", esta função examina os valores de várias variáveis ​​de ambiente para determinar o nome do usuário. Portanto, essa função não deve ser usada para fins de controle de acesso (ou possivelmente para qualquer outro propósito, pois permite que qualquer usuário se faça passar por outro) ). "

Konstantin Tenzin
fonte
100
Parece que esta função examina os valores de várias variáveis ​​de ambiente para determinar o nome do usuário. Portanto, essa função não deve ser usada para fins de controle de acesso (ou possivelmente para qualquer outra finalidade, pois permite que qualquer usuário se faça passar por outra).
911 Greg Hewgill
25
Não há nada de errado com getpass.getuser (), pois não afirma autenticar o usuário. O objetivo da função é determinar quem o usuário está reivindicando ser sem perguntar diretamente ao usuário.
Walker Hale IV
7
Isso não funciona se você fez um su. $ echo $ USER hithwen $ su julia Senha: $ echo $ USER julia $ python >>> import getpass >>> getpass.getuser () 'hithwen'
hithwen
6
O @GregHewgill levanta um ponto muito bom, mas, de fato, descobrir o nome de usuário de uma maneira simples e não autenticada, como essa, tem alguns aplicativos. Meu caso de uso atual: marcar alguns recursos de teste compartilhados com um nome de usuário para facilitar a limpeza posteriormente. (Por isso é mais fácil de descobrir quem bagunça é quem.)
driftcatcher
16
E eu concordo com o @GregHewgill para fins de controle de acesso, mas discordo completamente de 'qualquer outro objetivo' - é como dizer "Não use $ USER em um script de shell". Ótimo ponto sobre controle de acesso, mas existem muitos outros usos que não envolvem autenticação.
Nevelis
119

Sua melhor aposta seria combinar os.getuid()com pwd.getpwuid():

import os
import pwd

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

Consulte os documentos pwd para obter mais detalhes:

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

Liam Chasteen
fonte
51
Alternativamente (ligeiramente mais agradável para ler): pwd.getpwuid(os.getuid()).pw_name.
Brian M. Caça
6
O que isso faz no Windows? Talvez alguém possa tentar fazer isso e, se falhar, recorrer aos métodos ruins 'getpass / env var'.
9788 Jonathan Steinley
2
Esta é a maneira correta se você precisar obter o nome de usuário com e sem efetuar login.
Derrick Zhang
5
@JonathanHartley:ImportError: No module named pwd
Justin
1
Este método é utilizado em sistemas unix, muito superiores à resposta de Konstantin Tenzin, porque trata o sudocaso corretamente. (Estou ciente do didn OP '; t pedir unix-like ssytems.)
halloleo
86

Você também pode usar:

 os.getlogin()
Marcin Augustyniak
fonte
29
No linux, getlogin () retorna o nome do "usuário conectado no terminal de controle do processo". Portanto, falha quando não há terminal de controle, por exemplo, em um aplicativo mod_python.
Vebjorn Ljosa
23
Não disponível para Windows
Walker Hale IV
3
Se você usou su, isso não retornará o usuário atual, mas o usuário conectado originalmente.
Trevor Allred
4
funciona no Windows ... Python 3.4.1 (v3.4.1: c0e311e010fc, 18 de maio de 2014, 10:38:22) [MSC v.1600 de 32 bits (Intel)] no win32 Digite "help", "copyright", "créditos" ou "licença" para mais informações. >>> import os; os.getlogin () 'jrb'
Naib
5
Está disponível apenas no Windows para Python 3.x.
Zitrax 9/09/15
71

Você provavelmente pode usar:

os.environ.get('USERNAME')

ou

os.environ.get('USER')

Mas não será seguro porque as variáveis ​​de ambiente podem ser alteradas.

Nadia Alramli
fonte
18
os.getenv(...)foi descontinuado em favor de os.environ[...].
Mike Graham
11
Não deveria ser USER em vez de USERNAME?
22412 Karl Bartel
7
@MikeGraham os.getenvnão parece ser preterido ..?
DBR
4
Sim, exatamente USER x USERNAME é exatamente o que não é portátil, por isso não fornece a resposta correta.
Peter M
2
USERNAME é para Windows, USER é para Linux
Sabrina
22

Isso pode funcionar. Não sei como eles se comportam quando executam como serviço. Eles não são portáteis, mas é o que os.namee ifdeclarações são para.

win32api.GetUserName()

win32api.GetUserNameEx(...) 

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

Adão
fonte
30
Essa resposta é pelo menos tão útil quanto a (inútil) resposta univotada de 25 votos e unix.
Tom B
3
> "Pelo menos tão útil" Concordou. Presumivelmente, a resposta certa é uma combinação dos dois.
Jonathan Hartley
Se você está preso no python 2 no Windows, esta é a única maneira segura de fazer isso. Todas as outras formas podem ser enganados pela execução SET USERNAME=FAKEantes de seu comando python
CodeKid
21

Se você precisar disso para obter o diretório inicial do usuário, abaixo poderá ser considerado portátil (pelo menos win32 e linux), parte de uma biblioteca padrão.

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

Além disso, você pode analisar essa string para obter apenas o último componente do caminho (por exemplo, nome de usuário).

Consulte: os.path.expanduser

HezniK
fonte
9
O diretório inicial de alguém nem sempre reflete seu nome de usuário.
dreamlax
Isso funciona em Linux e Windows
Sabrina
Infelizmente, se você definir a variável HOME no Windows, isso retornará esse valor.
GLRoman
15

Para mim, usar o osmódulo é o melhor para portabilidade: funciona melhor no Linux e no 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]           

Resultado:

Janelas:

Dir home do usuário: C: \ Users \ myuser

nome de usuário: myuser

Linux:

Dir home do usuário: / root

nome de usuário: root

Não há necessidade de instalar nenhum módulo ou extensão.


fonte
16
Essa solução é inteligente, mas faz algumas suposições que nem sempre são verdadeiras. Não há nenhuma restrição que exija que o nome de usuário apareça no caminho do homedir no Linux. É o que acontece na maioria das vezes, mas um administrador de sistema pode definir o nome de usuário de um usuário para o que quiser.
9338 Joe Holloway
Definir a variável HOME derrota isso.
GLRoman 22/04
11

Combinado pwde getpassabordagem, com base em outras respostas:

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()
anatoly techtonik
fonte
9

Para UNIX, pelo menos, isso funciona ...

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

edit: Eu apenas procurei e isso funciona no Windows e UNIX:

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

No UNIX, ele retorna seu nome de usuário, mas no Windows, retorna o grupo de usuários, barra, seu nome de usuário.

-

IE

UNIX retorna: "nome de usuário"

O Windows retorna: "domínio / nome de usuário"

-

É interessante, mas provavelmente não é o ideal, a menos que você esteja fazendo algo no terminal de qualquer maneira ... nesse caso, você provavelmente usaria os.systempara começar. Por exemplo, há um tempo atrás eu precisava adicionar meu usuário a um grupo, então fiz (isso é no Linux, lembre-se)

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"

Eu sinto que é mais fácil de ler e você não precisa importar pwd ou getpass.

Também sinto que ter "domínio / usuário" pode ser útil em certos aplicativos no Windows.

dylnmc
fonte
1
Windows retorna domain/user nãogroup/user
RealHowTo 4/14
4
O módulo de comandos não funciona no Windows. É um módulo específico do UNIX (consulte docs.python.org/2/library/commands.html ). Agora está obsoleto e o subprocesso é recomendado. user = subprocess.check_output("whoami").replace("\r\n", "")
ConnectedSystems
k; Em seguida, use subprocess ...
jeez
2 observações. commands.whoami se saiu bem, mesmo no contexto de um serviço executado sob um nome de usuário diferente. ou seja, com chpst -u nobody python ./manage.py celerycam --pidfile=/var/run/celerycam/celerycam.pid eu não tenho ninguém . segundo, user = subprocess.check_output("whoami").strip() é mais portátil que os feeds de linha de substituição acima. commandsvs subprocessparece nitpicky mas comandos está faltando python 3.
JL Peyret
5

Escrevi o módulo plx há algum tempo para obter o nome do usuário de maneira portátil no Unix e no Windows (entre outras coisas): http://www.decalage.info/en/python/plx

Uso:

import plx

username = plx.get_username()

(requer extensões win32 no Windows)

decalque
fonte
4

Usando apenas bibliotecas python padrão:

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

Funciona em Windows, Mac ou Linux

Como alternativa, você pode remover uma linha com uma chamada imediata:

from os import environ,getcwd
user = (lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"])()
ThisGuyCantEven
fonte
1
getpass também é uma lib padrão
jodag 12/02
não funciona para mim no win10, python3.7.4. acho que está reclamando que 'USER' não foi encontrado em variáveis ​​ambientais. Eu acho que o getpass é uma escolha melhor de qualquer maneira.
Rika
3

Você pode obter o nome de usuário atual no Windows acessando a API do Windows, embora seja um pouco complicado invocar por meio dos tipos FFI ( GetCurrentProcessOpenProcessTokenGetTokenInformationLookupAccountSid ).

Eu escrevi um pequeno módulo que pode fazer isso diretamente do Python, getuser.py . Uso:

import getuser
print(getuser.lookup_username())

Funciona no Windows e no * nix (este último usa o pwdmódulo conforme descrito nas outras respostas).

Michael Kropat
fonte