Linux下基于Shell脚本,编写简单的学生成绩管理系统

免责声明:学生作品,水平有限,有问题请自行百度,谢谢

1. Linux下基于Shell脚本,编写简单的学生成绩管理系统,系统分为教师模块、学生模块。主要功能为教师通过系统添加、修改、删除、查看学生成绩;学生可查看成绩。该学生成绩管理系统的具体功能如下:

  1. 系统允许教师或学生登录
  2. 系统允许教师添加学生成绩,实现各科分数求和
  3. 系统允许教师修改学生成绩,修改成绩时自动更新总分
  4. 系统允许教师删除学生成绩
  5. 系统允许教师、学生查看成绩
  6. 退出系统
  1. 实验步骤
  1. 利用hostnamectl命令将主机名修改为自己的名字:

hostnamectl set-hostname studentName  // studentName是自己的名字

  1. 创建3个学生用户(stu1、stu2、stu3)和2个教师用户(tea1、tea2),学生用户属于student用户组,教师用户属于teacher用户组,并建立学生现有成绩数据集。
  2. 步骤 1: 创建用户组

    打开终端或命令行界面,并使用以下命令创建用户组:

  3. sudo groupadd student sudo groupadd teacher

  4. 步骤 2: 创建学生用户并添加到student用户组

    接下来,我们将创建三个学生用户,并将它们添加到student用户组:

    这里的-m选项告诉useradd为用户创建家目录(通常位于/home/用户名),-g选项指定用户的初始登录组。

  5. sudo useradd  -g student stu1

    sudo useradd  -g student stu2 s

    udo useradd  -g student stu3

    步骤 3: 创建教师用户并添加到teacher用户组

    类似地,我们将创建两个教师用户,并将它们添加到teacher用户组:

  6. sudo useradd -g teacher tea1

    sudo useradd -g teacher tea2

    验证

    你可以通过查看/etc/group文件来验证用户是否已正确添加到相应的用户组中:

  7. grep student /etc/group
  8. grep teacher /etc/group
  9. 设计学生成绩管理系统,具体要求如下:

A、进入系统后需先登录系统,主界面如下:

----------------------------欢迎使用学生成绩管理系统------------------------------

*                1、学生身份登录系统                      *

*                2、教师身份登录系统                      *

*                3、退出学生成绩管理系统                      *

----------------------------------------------------------------------------------------

  1. 如以学生身份登录系统,系统显示的主界面如下:

----------------------欢迎使用学生成绩管理系统(学生)------------------------

*                  1、学生查看成绩                        *

*                  2、学生退出系统                        *

----------------------------------------------------------------------------------------

 C、如以教师身份登录系统,系统显示的主界面如下:

----------------------欢迎使用学生成绩管理系统(教师)------------------------

*                  1、教师添加成绩                        *

*                  2、教师修改成绩                        *

*                  3、教师删除成绩                        *

*                  4、教师查看成绩                        *

*                  0、教师退出系统                        *

----------------------------------------------------------------------------------------

#! /bin/bash

#数据存储文件
DATA_FILE="grades.txt"
#每行遵循用户名,课程,成绩
#登陆界面
function show_menu {
#缩进只是为了代码可读性
	clear
	echo "------------欢迎使用学生成绩管理系统---------------------------"
	echo "*		1、学生身份登陆系统		*"
	echo "*		2、教师身份登陆系统		*"
	echo "*		3、退出学生成绩管理系统		*"
	echo "--------------------------------------------"
	read -p "请输入(1/2/3):" choice
	#-p显示提示信息 choice表示变量
	case $choice in
		1) student_login ;;#按1
		2) teacher_login ;;#按2
		3) exit 0 ;;
		*) echo "无效输入,重新输入"; show_menu ;;
		#结束标志
	#结束登录界面
#缩进是为了美观
	esac
}

#学生登录界面
function student_login {
	read -p "请输入你的学号:" username  # 获取用户输入的学号作为用户名

	# 检查用户名是否存在
	if grep -q "^$username," grades.txt; then
		student_menu $username  # 调用学生菜单函数,将学号作为参数传递
	else
		echo "无效的用户名,请重新输入!"
		student_login  # 重新调用登录函数,实现循环登录
	fi	
}
#学生功能菜单
function student_menu {
	local username=$1  # 使用传入的参数作为学号,并存储在局部变量中

	while true; do
		clear  # 清屏,清除终端中的内容

		echo "-------欢迎使用学生成绩管理系统(学生)-----------"
		echo "*		1、学生查看成绩		*"  # 提供学生查看成绩的选项
		echo "*		2、学生退出系统		*"  # 提供学生退出系统的选项
		echo "---------------------------------------------"

		read -p "请输入(1/2):" choice  # 获取用户输入的选项

		case $choice in
			1) view_grades $username ;;  # 如果用户输入1,调用查看成绩函数,并将学号作为参数传递
			2) show_menu ;;  # 如果用户输入2,返回主菜单
			*) echo "无效输入,重新输入" ;;  # 如果用户输入无效选项,输出提示信息
		esac
	done
}

#教师登录
function teacher_login {
	read -p "请输入教师号:" username  # 获取用户输入的教师号作为用户名

	if [[ "$username" == "tea1" || "$username" == "tea2" ]]; then
		teacher_menu $username  # 如果用户名是有效的,则调用教师菜单函数,并将教师号作为参数传递
	else
		echo "无效用户名,请重新输入!"  # 如果用户名无效,输出提示信息
		teacher_login  # 重新调用登录函数,实现循环登录
	fi
}
#教师功能菜单
function teacher_menu {
    local username=$1
    while true; do  
        clear  
        echo "----------欢迎使用教师功能菜单-----------------------"  
        echo "*		1、教师添加成绩		*"  
        echo "*		2、教师修改成绩		*"  
        echo "*		3、教师删除成绩		*"
        echo "*		0、教师退出			*"  
        echo "*		4、教师查看成绩		*" 
        echo "----------------------------------------"  
	read -p "请输入(1/2/3/4/0):" choice
	case $choice in
		1) add_grade $username ;;
		#按1
		2) edit_grade $username ;;
		#按2
		3) delete_grade $username ;;
		#按3
		4) view_local_grade ;;
		#按4
		0) show_menu ;;
		#按0
		*) echo "无效输入,请重新输入";;
	esac
done
}

# 添加成绩
function add_grade {
	read -p "请输入学生用户名:" stu_username  # 获取用户输入的学生用户名

	read -p "请输入课程名称:" course  # 获取用户输入的课程名称

	read -p "请输入成绩:" score  # 获取用户输入的成绩

	echo "$stu_username,$course,$score" >> $DATA_FILE  # 将学生用户名、课程名称和成绩以逗号分隔的格式写入数据文件末尾

	echo "成绩添加成功"  # 输出添加成功的提示信息
}
#编辑成绩
# 定义编辑成绩的函数  
function edit_grade {    
    # 定义数据文件名  
    local DATA_FILE="grades.txt"    
      
    # 读取用户输入的学生用户名  
    read -p "请输入学生用户名:" stu_username    
    # 读取用户输入的新成绩  
    read -p "请输入新成绩:" new_score    
    
    # 使用 awk 命令查找并替换成绩  
    # -v 选项用于在 awk 程序中定义变量,这里定义了 user 和 score 变量  
    awk -v user="$stu_username" -v score="$new_score" '    
    # BEGIN 块:设置输入字段分隔符 FS 和输出字段分隔符 OFS 为逗号  
    BEGIN { FS=","; OFS="," }    
    # 如果当前行的第一个字段(用户名)与 user 变量匹配  
    $1 == user {                 
        # 替换当前行的第三个字段(成绩)为 score 变量的值  
        $3 = score;              
    }    
    # 打印当前行(无论是否进行了修改)  
    { print }                    
    ' "$DATA_FILE" > tmp && # 将 awk 的输出重定向到临时文件 tmp,如果成功则执行后面的 mv 命令  
    mv tmp "$DATA_FILE"  # 将临时文件 tmp 替换原数据文件  
    
    # 输出提示信息  
    echo "成绩更新成功"    
}
#删除成绩
# 定义删除学生成绩的函数  
function delete_grade {    
    # 定义数据文件名  
    local DATA_FILE="grades.txt"    
    # 定义备份文件名,这里实际上后缀是多余的,但为了与DATA_FILE区分,保留  
    local BACKUP_FILE="${DATA_FILE}.txt"    
      
    # 读取用户输入的学生用户名  
    read -p "请输入学生用户名:" stu_username    
    
    # 使用 cp 命令备份原文件,确保在修改前有一个原始文件的副本  
    cp "$DATA_FILE" "$BACKUP_FILE" && # 备份成功则继续执行后面的命令  
      
    # 使用 sed 命令直接修改原文件,删除所有以指定用户名开头的行  
    # -i 选项表示直接修改文件内容  
    sed -i "/^${stu_username},/d" "$DATA_FILE" # 删除所有以 stu_username 开头(后面紧跟逗号)的行  
    
    # 检查上一个命令(sed)的退出状态  
    # $? 是一个特殊变量,保存了上一个命令的退出状态  
    if [ $? -eq 0 ]; then    
        # 如果 sed 命令成功执行(即 $? 的值为 0),则输出成功消息  
        echo "记录删除成功"    
    else    
        # 如果 sed 命令执行失败(即 $? 的值不为 0),则输出失败消息并恢复原始文件  
        echo "删除失败,可能未找到指定记录。已恢复原始文件。"    
        # 使用 mv 命令将备份文件恢复为原文件名,即恢复原始文件  
        mv "$BACKUP_FILE" "$DATA_FILE"    
    fi    
}
#查看成绩
# 定义查看成绩的函数  
function view_grades {    
    # 接收第一个参数作为用户名  
    local username=$1    
      
    # 检查是否提供了用户名  
    if [[ -n $username ]]; then    
        # 如果提供了用户名,则使用 grep 查找包含该用户名的行  
        # 并通过 while 循环读取每行,假设每行数据以逗号分隔  
        grep "^$username," "$DATA_FILE" | while IFS=',' read -r stu_username course score; do    
            # 打印当前行的学生用户名、课程和成绩  
            echo "学生:$stu_username,课程:$course,成绩: $score"    
        done    
    else    
        # 如果没有提供用户名,则显示所有成绩  
        echo "未提供用户名,显示所有成绩:"    
        # 使用 while 循环和重定向从文件中读取每行数据  
        while IFS=',' read -r stu_username course score; do    
            # 打印当前行的学生用户名、课程和成绩  
            echo "学生:$stu_username,课程:$course,成绩: $score"    
        done < "$DATA_FILE"    
    fi    
    
    # 在所有成绩显示后,等待用户按任意键继续  
    # 注意:这可能会在某些环境(如脚本直接运行时)中不起作用,因为它会阻塞终端  
    read -p "按任意键返回" key    
}  
  
# 注意:  
# 1. 此函数依赖于一个外部变量 $DATA_FILE,它应该在函数外部定义,并指向包含成绩数据的文件。  
# 2. `read -p "按任意键返回" key` 可能会在某些脚本执行环境中(如非交互式shell)导致问题,因为它会等待用户输入。  
# 3. 如果 $DATA_FILE 的每行数据格式不是严格的 "用户名,课程,成绩" 格式,或者包含额外的逗号,这个脚本可能需要进一步调整。  
# 4. 为了提高代码的健壮性,可以考虑添加对 $DATA_FILE 文件存在性和可读性的检查。
#教师查看成绩
# 定义查看本地成绩的函数  
function view_local_grade {    
    # 声明局部变量 stu_username 用于存储用户输入的学生用户名  
    local stu_username    
    # 声明并初始化局部变量 DATA_FILE,指定成绩数据文件的路径  
    local DATA_FILE="grades.txt"    
    
    # 提示用户输入要查找的学生的用户名  
    read -p "请输入查找的学生的用户名:" stu_username    
      
    # 检查用户是否提供了用户名  
    if [[ -n $stu_username ]]; then      
        # 如果提供了用户名,则使用 grep 命令查找包含该用户名的行  
        # 并通过管道将结果传递给 while 循环,使用 IFS=',' 设置字段分隔符为逗号  
        # 在循环中读取每行数据,并分别将用户名、课程和成绩赋值给相应的变量  
        grep "^$stu_username," "$DATA_FILE" | while IFS=',' read -r stu_username course score; do      
            # 打印当前行的学生信息,包括用户名、课程和成绩  
            echo "学生:$stu_username,课程:$course,成绩: $score"      
        done      
    else      
        # 如果用户未提供用户名,则显示所有成绩  
        echo "未提供用户名,显示所有成绩:"      
        # 使用 while 循环直接从文件中读取每行数据,并打印  
        # 注意这里不需要 grep,因为我们要读取所有行  
        while IFS=',' read -r stu_username course score; do      
            # 打印当前行的学生信息,包括用户名、课程和成绩  
            echo "学生:$stu_username,课程:$course,成绩: $score"      
        done < "$DATA_FILE"    # 使用重定向从文件中读取数据  
    fi      
      
    # 在所有成绩显示后,提示用户按任意键继续  
    # 注意:这将在终端等待用户输入,可能会在某些非交互式环境中造成问题  
    read -p "按任意键返回" key    
}  
  
# 注意:  
# 1. 该函数依赖于本地文件 grades.txt 的存在和可访问性。  
# 2. 如果用户输入的用户名不存在于文件中,grep 命令将不会输出任何内容,因此也不会显示任何与该用户名相关的成绩。  
# 3. 如果 grades.txt 文件的格式不是严格的 "用户名,课程,成绩" 格式,或者包含额外的逗号,这个脚本可能需要进一步调整。  
# 4. 在实际应用中,可能还需要添加额外的错误处理,比如检查文件是否存在、用户是否有权访问该文件等。
show_menu

  • 19
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值