1. I have two files, passwd and shadow
    a. Sort both files
    b. Compare both files line by line
      i. Match on user name output to third file
      ii. If it doesn’t match, output to fourth file
      iii. If user does not match, find which file the user is in
  2. Either passwd or shadow
  3. If user does not exist in passwd file check /home/test123
  4. Also look for home directory on the system, it may not be under /home
  5. If home directory exists, please add user
  6. Add useradd
  7. If home directory does not exist, delete the entry from the shadow file
  8. Use userdel (xxx)
  9. If home directory exits in another file system besides /home then create user and use home directory in the user entry
    a. Ex. /opt/murad
  10. After the changes are done, you have to run your comparison again,
  11. Now please use modules in your programming also called subroutines in shell programming and create a module called compare_files
  12. Please pass parameters to compare_files
  13. Create two modules,
    a. Check file()
      i. Use no match entries are empty
  14. Exit
  15. Create module subroutines

I have tried comparing them, but that's as far as I can come; I am stuck.

This is what I did so far:


# empty target file
cp /dev/null $match_file
cp /dev/null $not_match_file

# check username is exist in file
check_file() {
    exit_status=1 # username does not exist in file

    # read line by line
    while IFS=: read -r f1 f2 f3 f4 f5 f6 f7
        if [ "$f1" = "$username" ]; then
            exit_status=0 # username exist in file
    done <"$file"

    return $exit_status

# create module compare_file
compare_file() {

    # read line by line content of file_1
    while IFS= read -r line
        username=$(echo $line | awk -F: '{print $1}')

        # check username in file_1 is exist on file_2
        check_file "$username" "$file_2"
        if [ $? -eq 0 ]; then 
            #if user exist, write record to match_record.txt file
            #if user does not exist, write record to not_match_record.txt file

        echo $line >>$target_file

    done <"$file_1"

# short password files
echo "short $password_file"
sort $password_file > $password_file_sorted

# short shadow files
echo "short $shadow_file"
sort $shadow_file > $shadow_file_sorted

# compare file password with shadow
echo "check username in $password_file is exist on $shadow_file" 
compare_file $password_file_sorted $shadow_file_sorted

# compare file shadow with password 
echo "check username in $shadow_file is exist on $password_file" 
compare_file $shadow_file_sorted $password_file_sorted

# add or remove user
echo "for every mismatch username in $password_file, add user if home directory exist and remove user if home directory does not exist"
while IFS= read -r line
    username=$(echo $line | awk -F: '{print $1}')
    home_directory=$(echo $line | awk -F: '{print $6}')

    # check user does not exist in passwd
    num_entries_in_password=$(grep $username $password_file | wc -l)
    if [ $num_entries_in_password -eq 0 ]; then

       # check if /home/username directory exist
       if [ -d "/home/$username" ] ; then 
           echo "/home/$username directory exist, add $username with command: useradd $username"
           useradd $username
       elif [ -d $home_directory ]; then 
           # add user with specific user directory
           echo "$home_directory directory exist, add $username with command: useradd $username -b $home_directory"
           useradd $username -b $home_directory
           echo "remove user: $username"
           userdel $username

    echo "user: '$username' exist in $password_file"

done <"$not_match_file"

The output I am getting is short.  Why is that happening?

  • I'd start by pasting the code into shellcheck.net and addressing the errors/warnings it reports. May 14, 2019 at 11:09
  • You might also want to continue with a small (made up) example of the two source files that you can post here, along with your actual and expected results. May 14, 2019 at 19:33

1 Answer 1


Most likely this thread is dead, but I will still answer.
The problem you are having is in your sort.
Start with the passwd file, in a loop, sort user into one of two groups (use arrays) any user with a user id less than 1000 in one array, any user id 1000 or above in the other. Users less than 1000 are system user, the others are the users you are looking for.

In another loop I would filter out system users and check which users are not present in shadow file.

Note: any temporary files used should be written/store in the tmp directory.
Also: shadow file needs root access.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .