3

I tried to write a script which creates a user.

First it needs to check if:

  1. root is running
  2. if user maybe already exists

I Also tried to set the password equal to the username which was typed in.

Overall this works fine if i copy it step by step and execute it step by step. But the whole script won't work.

#!/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
2
  • 4
    "Won't work" is not a very useful statement. What happens? My guess it that you are explicitly executing it with a shell that doesn't support -p.
    – Chris Down
    Nov 28 '13 at 14:59
  • 1
    Also, you need if getent passwd "$username" ... with no [].
    – Joseph R.
    Nov 28 '13 at 15:00
3

The if command does not require square brackets. The condition part of the if statement is actually just a command and if that command exits sucessfully, the "true" part of the if statement is executed. The open square bracket is actually a command name (the close square bracket is just an argument passed to the [ command).

If you want to check that the username exists, do this:

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

Remove the "sleep 10". If I was using your script that would just irritate me.

2

The [ command introduces a conditional; it is synonymous with test except for requiring a closing bracket at the end. Inside the brackets, you need a condition such as -n "$foo" to test if a variable is non-empty, -e foo to test if a file exists, etc.

[ getent username>/dev/null 2>&1 ] is equivalent to test getent username>/dev/null 2>&1. The conditional expression is not well-formed, so this produces an error message such as [: 1: getent: unexpected operator, which is redirected to /dev/null so you don't see it. The conditional command returns 0 if the condition is true, 1 if it's false and 2 if there is an error; here it returns 2, and if takes then then branch only if the command returns 0, so the if statement takes the else branch.

You can get an idea of what's going on by activating traces by putting set -x as the second line of your script. This will tell you that the [ getent username>/dev/null 2>&1 ] command is executed followed by the useradd -m $username command, but to see why [ getent username>/dev/null 2>&1 ] is failing, you have to remove the redirection.

Since you don't want to use a conditional expression here, but to test if getent "$username" succeeds (not getent username, by the way), leave off the brackets:

if getent "$username" >/dev/null 2>&1; then …
0
1

I would have used this form which:

  • fix the usage error by stating the database to query (passwd)
  • doesn't require redirecting stdout
  • leave stderr alone as there is no point ignoring it

if [ "$(getent passwd username)" ]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.