Muitas vezes, quero obter o nome de login associado a um ID de usuário e, como provou ser um caso de uso comum, decidi escrever uma função shell para fazer isso. Embora eu use principalmente distribuições GNU/Linux, tento escrever meus scripts para serem tão portáteis quanto 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 com essa 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 getent
comando
Usar getent passwd
é mais portátil do que analisar /etc/passwd
, pois isso também consulta bancos de dados NIS ou LDAP não locais.
getent passwd "$uid" | cut -d: -f1
Infelizmente, o getent
utilitário não parece ser especificado pelo POSIX.
Use o id
comando
id
é o utilitário padronizado POSIX para obter dados sobre a identidade de um usuário.
As implementações BSD e GNU aceitam um User ID como um operando:
- id(1) - páginas de manual do OpenBSD
- id(1) – página de manual do FreeBSD
- GNU Coreutils: invocação de id
Isso significa que pode ser usado para imprimir o nome de login associado a uma ID de usuário:
id -nu "$uid"
No entanto, fornecer IDs de usuário como o operando não é especificado em POSIX; ele descreve apenas o uso de um nome de login como operando.
Combinando todos os itens 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; ele 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 analisa e armazena o status de saída de cada invocação 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 de usuário?