Muitas vezes, quero obter o nome de login associado a um ID de usuário e, como é um caso de uso comum, decidi escrever uma função de shell para fazer isso. Enquanto eu uso principalmente distribuições GNU / Linux, tento escrever meus scripts para serem o mais portáveis possível e verificar se o que estou fazendo é compatível com POSIX.
Analisar /etc/passwd
A primeira abordagem que tentei foi analisar /etc/passwd(usando awk).
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
No entanto, o problema dessa abordagem é que os logins podem não ser locais, por exemplo, a autenticação do usuário pode ser via NIS ou LDAP.
Use o getentcomando
O uso getent passwdé mais portátil do que a análise, /etc/passwdpois também consulta bancos de dados NIS ou LDAP não locais.
getent passwd "$uid" | cut -d: -f1
Infelizmente, o getentutilitário não parece ser especificado pelo POSIX.
Use o idcomando
id é o utilitário padronizado do POSIX para obter dados sobre a identidade de um usuário.
As implementações BSD e GNU aceitam um ID do usuário como um operando:
- id (1) - páginas de manual do OpenBSD
- id (1) - Página de manual do FreeBSD
- GNU Coreutils: chamada de identificação
Isso significa que ele pode ser usado para imprimir o nome de login associado a um ID do usuário:
id -nu "$uid"
No entanto, fornecer IDs do usuário como operando não é especificado no POSIX; descreve apenas o uso de um nome de login como o operando.
Combinando todas as opções acima
Eu considerei combinar as três abordagens acima em algo como o seguinte:
get_username(){
uid="$1"
# First try using getent
getent passwd "$uid" | cut -d: -f1 ||
# Next try using the UID as an operand to id.
id -nu "$uid" ||
# As a last resort, parse `/etc/passwd`.
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
}
No entanto, isso é desajeitado, deselegante e - mais importante - não robusto; sai com um status diferente de zero se o ID do usuário for inválido ou não existir. Antes de escrever um script de shell mais longo e desajeitado que analise e armazene o status de saída de cada chamada de comando, pensei em perguntar aqui:
Existe uma maneira mais elegante e portátil (compatível com POSIX) de obter o nome de login associado a um ID do usuário?
getentnem idvai retornar nada passado o primeiro jogo; a única maneira de encontrar todos eles é enumerar todos os usuários, se o banco de dados do usuário permitir. (Procurando /etc/passwdtrabalhos para usuários definidos lá, obviamente).
/etc/passwde /etc/shadowpara testar esse cenário e verifiquei que ambos ide getent passwdse comportam como você descreve. Se, em algum momento, eu acabar usando um sistema em que um usuário tem vários nomes, farei o mesmo que esses utilitários de sistema e simplesmente tratarei a primeira ocorrência como o nome canônico desse usuário.
setuid(some_id), e não há requisitos que some_idpossam fazer parte de qualquer banco de dados do usuário. Com coisas como namespaces de usuário no Linux, isso pode se tornar uma suposição incapacitante para seus scripts.
getpwuid()função que lsusa para converter UIDs em nomes de login. A resposta de Gilles é uma maneira mais direta e eficiente de conseguir isso.