O comando [ introduz um condicional; é sinônimo de test exceto pela exigência de um colchete de fechamento em o fim. Dentro dos parênteses, você precisa de uma condição como -n "$foo" para testar se uma variável não está vazia, -e foo para testar se existe um arquivo, etc.
[ getent username>/dev/null 2>&1 ] é equivalente a test getent username>/dev/null 2>&1 . A expressão condicional não é bem formada, portanto, isso produz uma mensagem de erro, como [: 1: getent: unexpected operator , que é redirecionada para /dev/null para que você não a veja. O comando condicional retorna 0 se a condição for verdadeira, 1 se for falso e 2 se houver um erro; aqui ele retorna 2, e if leva então then branch somente se o comando retornar 0, então a instrução if pega a ramificação else .
Você pode ter uma ideia do que está acontecendo, ativando rastreios colocando set -x como a segunda linha do seu script. Isso lhe dirá que o comando [ getent username>/dev/null 2>&1 ] é executado seguido pelo comando useradd -m $username , mas para ver porque o [ getent username>/dev/null 2>&1 ] está falhando, você deve remover o redirecionamento.
Como você não quer usar uma expressão condicional aqui, mas para testar se getent "$username" é bem-sucedido (não getent username , a propósito), deixe os colchetes:
if getent "$username" >/dev/null 2>&1; then …