Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back > Forums > Linux Forums > Linux - Newbie
User Name
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!


Search this Thread
Old 11-06-2011, 01:10 PM   #1
LQ Newbie
Registered: Nov 2011
Posts: 1

Rep: Reputation: Disabled
Cool Create accounts from text file or database

Hi guys,

I want to create a bash script that creates accounts using the information from a text file;

First Name Last Name Username Password

Using the information above to create OS accounts and add them to groups.

why is it better to use awk instead of grep. Ive never coded in bash before. advice is appreciated
Old 11-06-2011, 05:31 PM   #2
Nominal Animal
Senior Member
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Here is one option using a Bash script. Start the script with a test that outputs usage if the user runs the script without any arguments:

if [ $# -lt 1 ] || [*"$1" == "-h" ] || [ "$1" == "--help" ]; then
    exec >&2
    echo ""
    echo "Usage: $0 [ -h | --help ]"
    echo "       $0 account-file(s)..."
    echo ""
    echo "This script will create normal user accounts."
    echo "Each line in the account file that matches"
    echo "       username password Full Name"
    echo ""
    echo "User name must start with a letter, and contain"
    echo "only ASCII letters A-Z, digits 0-9, dashes -,"
    echo "dots ., and underscores _."
    echo ""
    echo "Password cannot contain spaces or colons(:)."
    echo "Full Name must not contain colons (:) or commas (,)."
    echo ""
    exit 0

# Spaces and tabs separate values on each line.
Note that I reordered the fields. Username is the most important field, so it is logical to list first. Neither the username or password should contain spaces, so anything after the password is considered the Full Name. Since we set the password using chpasswd , it is best to disallow colons in the password too.

If you want to support spaces, you will need define a specific character as your delimiter (value of IFS above; "" is the default, any whitespace). Comma, colon or pipe ( , : | ) are the most typical ones used for something like this.

Next, start a loop over all input files. It is customary to abort the script if a file does not exist.
while [ $# -gt 0 ]; do
    if [ ! -f "$1" ]; then
        echo "$1: File not found." >&2
        exit 1
You'll need to loop over each input line, too. (We'll tell the loop where to read from at the end of the loop, so just ignore that detail for now). Ignore lines with empty username or password.
    while read user pass full ; do
        [ -n "$user" ] || continue
        [ -n "$pass" ] || continue
Ignore invalid usernames, passwords, and full names.
        [ "${user#[A-Za-z]}" == "$user" ] && continue
        [ "${user//[-._0-9A-Za-z]/}" == "" ] || continue
        [ "${pass//[:]/}" == "$pass" ] || continue
        [ "${full//[:,]/}" == "$full" ] || continue
Next, you need to decide what do do if the user account already exists. To skip already existing users, use
        if id -u "$user" &>/dev/null ; then
            echo "User '$user' already exists." >&2
but if you want the script to halt at that point, change the continue to exit 1.

Next, use useradd to create the user account, and chpasswd to set the password.
        sudo useradd -m -U -c "$full,,," "$user" || exit $?
        builtin echo "$user:$pass" | sudo chpasswd || exit $?
Normally you never specify the password on the command line for any command. The above is a rare exception: In a Bash script you can safely specify the password as a parameter to a builtin command. The builtin keyword tells Bash to always use the built-in echo, and not an alias; this makes sure the password is not visible (outside this shell script).

It is important to remember that the parameters for every process are visible to all users on that machine, even unprivileged ones. However, because Bash (and other shells) handle built-in commands internally, they are not run as separate processes, and therefore the parameters are not visible. Making sure you use the actual built-in command (and not an alias or some such) is important.

Next, you might wish to output the details on the user the script just created.
        echo "Created user '$user', full name '$full'."
Finally, we end the line-reading inner loop. To make the read built-in to read from the file, we add input redirection here. If there is a problem in reading the file, halt the script.
    done < "$1" || exit $?
The current file has been handled at this point. So, before closing the outer loop, we shift all command-line parameters one place to the left, removing the first one ($1). This way we will process through all command-line parameters in order, from left to right, with $1 being the "current" parameter in each outer loop iteration.
    shift 1
That is about it, I think. Since I intended this as an example, to guide and help you develop your own script, I have not actually tested if the above runs. (The logic is sound, but typos might lurk somewhere.)

I expect you to do the testing. If you find any errors, or there are points in the script you do not understand, say so, and I shall try to fix and explain.

If you obtain the data from some other source, you need to redefine the two loops. Remember, the outer loop loops over files (databases), and the inner loop loops over lines (records). The data source does not matter much.

My own preferred solution is a bit more complex. Instead of immediately creating each user, I would store them in a list structure, with one list of new accounts, and another list for accounts that will not be created (because they exist already, or the username is unacceptable, et cetera). When all account information has been read, I would report the statistics to the user running the script, and ask to confirm. That way, the user can make an intelligent decision on whether or not to create any user accounts. It is important if not all of the accounts can be created.
However, that results in a bit more complex script, and I was afraid that if I were to show you that one, you'd just use it blindly without understanding how it works. And I would rather have you write your own scripts. Something as important as user account creation should not be done willy-nilly; you need to be careful, and know what you are doing.

Fruitful scripting,


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Text file data into Postgres database Sum1 Linux - Software 11 06-23-2009 05:10 PM
Why cant the database create a new file with write permissions dappa_don Linux - Server 1 05-28-2009 04:38 AM
bash script to create text in a file or replace value of text if already exists knightto Linux - Newbie 5 09-11-2008 12:13 AM
text match pipe to file then delete from original text file create new dir automatic tr1px Linux - Newbie 6 09-10-2008 10:40 PM
PAM accounts from a text file paul_mat Linux - Software 1 11-07-2005 01:33 AM

All times are GMT -5. The time now is 08:23 PM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration