Por que minha condição é sempre falsa?

3

Eu tentei escrever um script que cria um usuário.

Primeiro, precisa verificar se:

  1. root está sendo executado
  2. se o usuário talvez já exista

Eu também tentei definir a senha igual ao nome de usuário que foi digitado.

No geral, isso funciona bem se eu copiá-lo passo a passo e executá-lo passo a passo. Mas todo o roteiro não funcionará.

#!/bin/bash
if [ "$(id -u)" = "0" ]; then
    read -p "User: " username
    pass=$username

    if [ getent username>/dev/null 2>&1 ]; then
        echo "$username already exists"
        sleep 10
        exit 1
    else    
        useradd -m $username
        echo "$pass" | passwd $username --stdin
        [ $? -eq 0 ] && echo "User was created" || echo "Error while creating"
        unset username

    fi
else
    echo "No root"
    sleep 3
    exit 2  
fi
    
por BlueFox 28.11.2013 / 15:56

3 respostas

2

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 …
    
por 29.11.2013 / 02:07
3

O comando if não requer colchetes. A parte de condição da instrução if é, na verdade, apenas um comando e, se esse comando sair com êxito, a parte "true" da instrução if será executada. O colchete aberto é, na verdade, um nome de comando (o colchete de fechamento é apenas um argumento passado para o comando [ ).

Se você quiser verificar se o nome de usuário existe, faça o seguinte:

if getent passwd $username &>/dev/null; then ...

Remova o "sleep 10". Se eu estivesse usando o seu script, isso me irritaria.

    
por 28.11.2013 / 16:15
1

Eu teria usado este formulário que:

  • corrija o erro de uso informando o banco de dados a consultar ( passwd )
  • não requer redirecionamento de stdout
  • deixe o stderr sozinho, pois não faz sentido ignorá-lo
if [ "$(getent passwd username)" ]
    
por 29.11.2013 / 04:09