Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7864733
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 2, 20262026-06-02T23:52:29+00:00 2026-06-02T23:52:29+00:00

This shell script is supposed to add users to the system. The new users

  • 0

This shell script is supposed to add users to the system. The new users details are in a file. The shell is rejecting this script with the message:

syntax error near unexpected token 'done'.

What’s wrong?

#!/bin/bash
#Purpose: Automatically add new users in a linux system based upon the data found within a text file
#         Assign encryped passwords to each user
#         Add users to groups or create new groups for these users
#         Report errors and successful operations where necessary in log files
#         post help options (echo)

#Root validation
if [[ $(id -u) -eq 0 ]]; then
  #Argument validation
  if [[ -z "$1" ]]; then
    echo "No arguments found!"
    echo "Please include a user detail text file as first argument"
    echo "Please include a report text file as second argument"
    echo "Please include an error report text file as the third argument"
    echo "Use the -h argument (i.e. ./script -h) for help"
  exit 1
fi

#Help validation and Help file
if [[ "$1" = "-h" ]]; then
  echo "This is the help information file"
  echo "This script is designed to add users to a linux system by reading information from a user detail file (such as userlist.txt)"
  echo "The format of this user detail text file is "username password groupname fullname" seperated using TAB spacing"
  echo "This script will read the first argument as the user detail file, the second and third arguments will be read as a success report file and error report file respectively"
  exit
fi

#Reads first argument as user detail file for data
cat userlist.txt | while read uname password gname fullname
#Reads /etc/passwd for Username
egrep -w "^$uname" /etc/passwd
#If Username is found then error reports
if [ $? == 0 ]; then
  echo "User Already Exists : Error adding user with username $uname;$gname;$fullname" >> Successes1.log
  exit 1
else
  #Reads /etc/group for Groupname
  egrep -w "^$gname" /etc/group
  #If Groupname is found then nothing
  if [ $? == 0 ]; then
    echo ""
  else
    #If Groupname not found then creates new group and reports
    groupadd "$gname"
    echo "Group Not Found: New Group $gname was created" >> Successes1.log
  fi
  #Retrieves Date
  createddate=$(date)
  #Perl password script takes input from Userlist
  pass=$(perl -e 'print crypt($ARGV[0], "Password")' "$password")
  #Adds Users with variables from userlist
  useradd "$uname" -g "$gname"  -c "$fullname" -p "$pass"
  #Reports information to successlist and errorlist report files
  if [ $? == 0 ]; then
    groupid=$(id -g $uname)
    userid=$(id -u $uname)
    echo "User Successfully Added: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Successes1.log
  else
    groupid=$(id -g $uname)
    userid=$(id -u $uname)
    echo "Useradd Error Occurred: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Errors1.log
    echo "Error: Must be root user to execute script"
    exit
  fi
done

Second attempt

Using some of the ideas from the answers, I came up with a second attempt:

#!/bin/bash
#Purpose: Automatically add new users in a linux system based upon the data found within a text file
#         Assign encryped passwords to each user
#         Add users to groups or create new groups for these users
#         Report errors and successful operations where necessary in log files
#         post help options (echo)

#Root validation
if [[ $(id -u) -eq 0 ]]; then
  #Argument validation
  if [[ -z "$1" ]]; then
    echo "Usage: $0 usernames report errors" 1>&2
    echo "Please include a user detail text file as first argument"
    echo "Please include a report text file as second argument"
    echo "Please include an error report text file as the third argument"
    echo "Use the -h argument (i.e. ./script -h) for help"
    exit 1
  fi
fi

#Help validation and Help file
if [[ "$1" = "-h" ]]; then
  echo "This is the help information file"
  echo "This script is designed to add users to a linux system by reading information from a user detail file (such as userlist.txt)"
  echo "The format of this user detail text file is "username password groupname fullname" seperated using TAB spacing"
  echo "This script will read the first argument as the user detail file, the second and third arguments will be read as a success report file and error report file respectively"
  exit
fi

#Reads first argument as user detail file for data
cat jan.txt | while read uname password gname fullname; do
#Reads /etc/passwd for Username
 egrep -w "^$uname:" /etc/passwd >/dev/null 2>&1
#If Username is found then error reports
if [ $? == 0 ] 
then
  echo "User Already Exists : Error adding user with username $uname;$gname;$fullname" >> Errors1.log

else
  #Reads /etc/group for Groupname
  egrep -w "^$gname" /etc/group
  #If Groupname is found then nothing
if [ $? == 0 ]; then
    echo ""
else
  #If Groupname not found then creates new group and reports
  groupadd "$gname"
    echo "Group Not Found: New Group $gname was created" >> Successes1.log
done < $1
#Retrieves Date
createddate=$(date)
#Perl password script takes input from Userlist
pass=$(perl -e 'print crypt($ARGV[0], "Password")' "$password")
#Adds Users with variables from userlist
useradd "$uname" -g "$gname"  -c "$fullname" -p "$pass"
#Reports information to successlist and errorlist report files
if [ $? == 0 ]
then
  groupid=$(id -g $uname)
  userid=$(id -u $uname)
  echo "User Successfully Added: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Successes1.log
else
  groupid=$(id -g $uname)
  userid=$(id -u $uname)
  echo "Useradd Error Occurred: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Errors1.log
  echo "Error: Must be root user to execute script"
  exit 1
fi
fi
done

This does not seem to work properly either. What’s wrong now?
Seems to show arguments and runs however no users nor group have been added therefore no logs have been created

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-02T23:52:31+00:00Added an answer on June 2, 2026 at 11:52 pm

    The if starting at:

    if [ $? == 0 ]; then
      echo "User Already Exists : Error adding user with username ...
      exit 1
    else
    

    is ended with the done instead of the fi that is required.

    The while loop starting a couple of lines earlier:

    cat userlist.txt | while read uname password gname fullname
    

    is missing its do (another bug); if that was present, then it would also need the done at the end. Someone lost track of the indentation. (Using 2 characters per level is better than 0 or 1, but it is easier to track levels if you use 4 spaces per level.) Note that the shell hasn’t gotten around to complaining about the lack of do because the syntax for a while loop is:

    while cmd1
          cmd2
          cmd3 ...
    do
    

    and as far as the shell is concerned, it is still processing commands in the list cmd1, cmd2, cmd3, ....


    Here’s a semi-decently indented version of the script. There was a missing fi at the top of the script, too.

    #!/bin/bash
    #Purpose: Automatically add new users in a linux system based upon the data found within a text file
    #         Assign encryped passwords to each user
    #         Add users to groups or create new groups for these users
    #         Report errors and successful operations where necessary in log files
    #         post help options (echo)
    
    #Root validation
    if [[ $(id -u) -eq 0 ]]
    then
        #Argument validation
        if [[ -z "$1" ]]
        then
            echo "No arguments found!"
            echo "Please include a user detail text file as first argument"
            echo "Please include a report text file as second argument"
            echo "Please include an error report text file as the third argument"
            echo "Use the -h argument (i.e. ./script -h) for help"
            exit 1
        fi
    fi
    
    #Help validation and Help file
    if [[ "$1" = "-h" ]]
    then
        echo "This is the help information file"
        echo "This script is designed to add users to a linux system by reading information from a user detail file (such as userlist.txt)"
        echo "The format of this user detail text file is "username password groupname fullname" seperated using TAB spacing"
        echo "This script will read the first argument as the user detail file, the second and third arguments will be read as a success report file and error report file respectively"
        exit
    fi
    
    #Reads first argument as user detail file for data
    cat userlist.txt | while read uname password gname fullname
    do
        #Reads /etc/passwd for Username
        egrep -w "^$uname" /etc/passwd
        #If Username is found then error reports
        if [ $? == 0 ]
        then
            echo "User Already Exists : Error adding user with username $uname;$gname;$fullname" >> Successes1.log
            exit 1
        else
            #Reads /etc/group for Groupname
            egrep -w "^$gname" /etc/group
            #If Groupname is found then nothing
            if [ $? == 0 ]
            then
                echo ""
            else
                #If Groupname not found then creates new group and reports
                groupadd "$gname"
                echo "Group Not Found: New Group $gname was created" >> Successes1.log
            fi
            #Retrieves Date
            createddate=$(date)
            #Perl password script takes input from Userlist
            pass=$(perl -e 'print crypt($ARGV[0], "Password")' $pass)
            #Adds Users with variables from userlist
            useradd "$uname" -g "$gname"  -c "$fullname" -p "$pass"
            #Reports information to successlist and errorlist report files
            if [ $? == 0 ]
            then
                groupid=$(id -g $uname)
                userid=$(id -u $uname)
                echo "User Successfully Added: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Successes1.log
            else
                groupid=$(id -g $uname)
                userid=$(id -u $uname)
                echo "Useradd Error Occurred: $uname;$userid;$gname;$groupid;$createddate;$fullname" >> Errors1.log
                echo "Error: Must be root user to execute script"
                exit
            fi
        fi
    done
    

    There is still much room for improvement. The root validation block should exit if the user is not root; that happens instead a mile further down inside the loop. You can check the number of arguments better: $# gives you the number of arguments. If I tried yourscript.sh '' arg2 arg3, you’d claim there were no arguments when in fact the problem is that $1 is present but is an empty string. The standard convention for reporting how to use a command is something like:

    echo "Usage: $0 usernames report errors" 1>&2
    

    This reports the command’s name, and the arguments expected. The 1>&2 sends the message to standard error instead of standard output. The logic here is a little bizarre even so. You check that the user is root and only then check that there are arguments. If the user is not root, you don’t check the arguments. Not entirely sensible, I submit.

    We can debate the UUOC (Useless Use of Cat). There’s actually an award for it; I don’t think this qualifies. However, it would be possible to write:

    while read uname password gname fullname
    do
        ...
    done < $1
    

    Hmmm…the script is supposed to take a file name argument that specifies the users, but the cat takes a fixed file name, not the file name argument!

    Similarly, arguments 2 and 3 are studiously ignored; the log files are hard-coded.

    egrep -w "^$uname" /etc/passwd
    #If Username is found then error reports
    if [ $? == 0 ]
    

    This fragment can be improved several ways:

    if egrep -w "^$uname:" /etc/passwd >/dev/null 2>&1
    then
        #If Username is found then error report
    

    This tests the exit status of the egrep command directly; it also prevents a new user roo from being treated as pre-existing because of user root. It sends the output and error output to /dev/null so that you won’t see anything when the user does exist.

    It might be better not to exit when the user name is found; you could at least try to process the next entry. It is also odd that the report that the user exists (which terminates the processing) is recorded in Successes1.log rather than in Errors1.log; it is treated like an error.

    The group check constructs are similar and should be similarly upgraded.

    You read the password into $password with the read line; when it comes to creating the password, though, you have:

    pass=$(perl -e 'print crypt($ARGV[0], "Password")' $pass)
    

    On the first cycle, $pass is empty (most probably); you should have used $password in double quotes at the end:

    pass=$(perl -e 'print crypt($ARGV[0], "Password")' "$password")
    

    As with the egrep commands, you can check the status of the useradd command directly too. It is a bit sweeping to say if [ $? == 0 ] is the mark of a tyro, but it isn’t too far off the truth.

    The final exit in the script should be exit 1 to indicate an error exit. As already noted, this is preceded by the comment about ‘you must be root’, even though there was a check at the top for root privileges.

    Caveat: I’ve not attempted to run the script; I could easily have missed some issues. It does, however, pass sh -v -n, so there are no gross syntactic errors left.

    Once a shell script is syntactically correct, then you normally debug it using sh -x script (or, if it takes arguments, then sh -x script arg1 arg2 arg3 ...). This is the execution trace mode. The shell tells you, more or less inscrutably, what it is doing. The information is written to standard error. You can even trap the output for later scrutiny if you like with:

    sh -x script arg1 arg2 arg3 2>script-x.log
    

    The 2>script-x.log notation sends the standard error to the file script-x.log (choose your own meaningful name; I often use x or xxx for files I won’t want to keep, but I also remove such files without necessarily even looking at them because I know they are throwaway files).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm creating a Shell Script, and I have a file like this called expressions.txt
A really simple shell script question. I have a file with something like this:
I have written this shell script as wrapper to a JAR file. The script
I am facing a problem in a bash shell script. This script is supposed
I'm writing a shell script that is supposed to be run by users only
I am new to this shell-script programming so need your help to write a
I came across this shell script for OSX and I don't understand the following:
For testing purposes I have this shell script #!/bin/bash echo $$ find / >/dev/null
What is current directory of shell script? Is this current directory from which I
I have one shell script opening a perl script. This perl script should be

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.