如何制作一个完整的 bash 脚本来比较影子文件和 passwd 文件?

如何制作一个完整的 bash 脚本来比较影子文件和 passwd 文件?
  1. 我有两个文件,passwd 和shadow
    a。对两个文件进行排序
    b.逐行比较两个文件
      i。匹配用户名输出到第三个文件
      ii。如果不匹配,则输出到第四个文件
      iii。如果用户不匹配,则查找用户在哪个文件中
  2. passwd 或shadow
  3. 如果用户不存在于 passwd 文件中,请检查 /home/test123
  4. 还要查找系统上的主目录,它可能不在 /home 下
  5. 如果主目录存在,请添加用户
  6. 添加用户add
  7. 如果主目录不存在,则从影子文件中删除该条目
  8. 使用 userdel (xxx)
  9. 如果主目录存在于 /home 之外的另一个文件系统中,则创建用户并在用户条目
    a 中使用主目录。前任。 /选择/穆拉德
  10. 更改完成后,您必须再次运行比较,
  11. 现在请在您的编程中使用模块(在 shell 编程中也称为子例程)并创建一个名为compare_files 的模块
  12. 请将参数传递给compare_files
  13. 创建两个模块,
    a.检查文件()
      i.使用无匹配条目为空
  14. 出口
  15. 创建模块子例程

我尝试过对它们进行比较,但这是我所能做到的。我被困住了。

这就是我到目前为止所做的:

#!/bin/sh
password_file=pass.txt
password_file_sorted="sorted_$password_file"
shadow_file=shadow.txt
shadow_file_sorted="sorted_$shadow_file"
match_file="match_record.txt"
not_match_file="not_match_record.txt"

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

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

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

    return $exit_status
}

# create module compare_file
compare_file() {
    file_1=$1
    file_2=$2

    # read line by line content of file_1
    while IFS= read -r line
    do
        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
            target_file=$match_file
        else
            #if user does not exist, write record to not_match_record.txt file
            target_file=$not_match_file
        fi

        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
do
    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
       else
           echo "remove user: $username"
           userdel $username
       fi 
    fi

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

done <"$not_match_file"

我得到的输出很短。为什么会发生这种情况?

答案1

很可能这个帖子已经死了,但我仍然会回答。
你遇到的问题是你的问题。
passwd文件开始,在循环中将用户排序到两个组之一(使用数组),一个数组中用户 ID 小于 1000 的任何用户,另一个数组中任何 ID 1000 或以上的用户。小于1000的用户为系统用户,其余为您要查找的用户。

在另一个循环中,我将过滤掉系统用户并检查哪些用户不存在于影子文件中。

注意:使用的任何临时文件都应写入/存储在 tmp 目录中。
另外:影子文件需要 root 访问权限。

相关内容