需求:
用Shell编程完成用户的注册及登录
完成
-
注册用户
-
用户名首字母大写
- 密码需8个字符及以上且含“$”,“&”,“-”中的任意一个
- 手机号需以139开头的11位号码
- 邮箱需以数字开头的qq.com
2.检测重复注册
3.注册信息写入/etc/secfinfe
4.用户登录
5.检测是否存在
脚本介绍
Shell编程实现用户注册及登录,不仅展示了用户管理系统的基本概念,还加深了对认证机制、数据存储和脚本编程技巧的理解,具有实际教学和开发价值。。以下是对Shell编程用户登录及注册的脚本的详细介绍(屏保显示指令“cmatrix”后文单独介绍):
#!/bin/bash
register() {
# 读取用户输入的用户名
read -p "请输入用户名(必须以大写字母开头): " username
# 代码的功能是检查 /etc/secfinfe 文件中是否已存在以 $username 开头并且后面跟着一个冒号(:)的行。
if grep -q "^$username:" /etc/secfinfe; then
# 如果用户名已存在,则输出提示信息并返回1
echo -e "\n用户名 '$username' 已存在,请选择其他用户名。\n"
return 1
fi
# 循环检查用户名格式是否正确 用一个 while 循环,用于验证用户输入的用户名 $username 是否符合特定的格式要求。具体来说,它检查用户名是否:(1)以一个大写字母开头(^[A-Z])。(2)紧接着是至少两个({2,})由大小写字母、数字或下划线([a-zA-Z0-9_])组成的字符。
while ! [[ $username =~ ^[A-Z][a-zA-Z0-9_]{2,}$ ]]; do
# 如果用户名格式不正确,则重新提示用户输入
read -p "无效的用户名格式。请输入以大写字母开头的用户名: " username
done
# 读取用户输入的密码(不显示输入内容)
read -sp "请输入密码(至少8个字符,并且包含'&', '$', '_'中的至少一个): " password
echo " "
# 检查密码长度和特殊字符,这是一个条件判断,用于验证变量 $password(可能是一个用户输入的密码)是否满足两个条件:(1)${#password} -lt 8:检查 $password 的长度是否小于 8。${#password} 会返回 $password 变量的长度(即字符数)。-lt 是一个数值比较运算符,表示“小于”(less than)。(2)
! $password =~ [\&\$\_]:使用正则表达式检查 $password 是否不包含特定的字符。在这个例子中,正则表达式 [\&\$\_] 匹配任意一个 &、$ 或 _ 字符。但是,由于前面有一个逻辑非运算符 !,所以这个条件实际上是检查 $password 是否不包含这些字符中的任意一个。如果 $password 的长度小于 8 或者不包含 &、$ 或 _ 这三个字符中的任意一个,那么整个条件判断的结果为真(即条件满足)。
if [[ ${#password} -lt 8 || ! $password =~ [\&\$\_] ]]; then
# 如果密码不符合要求,则重新提示用户输入,read -sp "提示信息" password 是用于在 Bash 脚本中读取用户输入的一个常用命令,其中 -s 选项用于在输入时隐藏字符(通常用于密码输入),-p 选项用于在读取之前打印提示信息。
read -sp "密码至少为8个字符,并且必须包含'&', '$', '_'中的至少一个,请重新输入密码: " password
echo " "
fi
# 读取用户输入的手机号码
read -p "请输入手机号码(必须以139开头): " phone
# 循环检查手机号码格式是否正确,这一个 while 循环,它使用一个正则表达式来检查变量 $phone 是否符合一个特定的电话号码格式:即以 "139" 开头,后面跟着 8 个数字。while ! ... ; do ... done:这是一个 while 循环的结构,它会持续执行循环体中的命令,直到条件表达式的值为假(即返回值为非零)。在这里,条件表达式前面有一个逻辑非 !,意味着只要条件表达式的值为真(即返回值为零),循环就会继续。
[[ $phone =~ ^139[0-9]{8}$ ]]:这是一个条件测试表达式,它使用 =~ 运算符来进行正则表达式匹配。这里检查 $phone 变量是否匹配正则表达式 ^139[0-9]{8}$。
while ! [[ $phone =~ ^139[0-9]{8}$ ]]; do
# 如果手机号码格式不正确,则重新提示用户输入
read -p "无效的手机号码。请输入以139开头的手机号码: " phone
done
# 读取用户输入的电子邮件地址
read -p "请输入电子邮件地址(必须以数字开头,并以 @qq.com 结尾): " email
# while 循环有一个正则表达式,它用于检查变量 $email 是否匹配特定的电子邮件地址格式,循环检查电子邮件地址格式是否正确
while ! [[ $email =~ ^[0-9].*@qq.com$ ]]; do
# 如果电子邮件地址格式不正确,则重新提示用户输入
read -p "无效的电子邮件地址。请输入以数字开头,并以 @qq.com 结尾的电子邮件地址: " email
done
# 将用户信息追加到/etc/secfinfe文件
echo "$username:$password:$phone:$email" >>/etc/secfinfe
# 输出注册成功信息
echo -e "\n用户注册成功!\n"
}
login() {
# 读取用户输入的用户名
read -p "请输入用户名: " username
# 读取用户输入的密码(不显示输入内容)
read -sp "请输入密码: " password
# 这里读取手机号码和电子邮件地址,但在本函数中没有实际使用它们进行验证
read -p "请输入手机号码: " phone
read -p "请输入电子邮件地址: " email
# 在一个 while 循环中结合 IFS(内部字段分隔符)和 read 命令来逐行读取/etc/secfinfe
文件,并将每一行的内容分配给多个变量。
while IFS=":" read -r stored_user stored_pass stored_phone stored_email; do
# 检查输入的用户名、密码和电子邮件地址是否与文件中的信息匹配
if [[ $username == "$stored_user" && $password == "$stored_pass" && $email == "$stored_email" ]]; then
echo -e "\n登录成功!欢迎,$username!\n"
cmatrix #屏保显示指令
return 0
fi
done < "/etc/secfinfe"
# 如果用户信息不匹配,则输出登录失败信息并返回1
echo -e "\n登录失败。用户名、密码、手机号或邮箱不匹配。\n"
return 1
}
# 主循环
while true; do
# 清屏
clear
# 输出欢迎信息和菜单选项
echo -e "欢迎\n"
echo "1. 注册"
echo "2. 登录"
echo "3. 退出"
# 读取用户的选择
read -p "请输入您的选择: " choice
# 根据用户的选择执行相应的操作
case $choice in
1)
register
;;
2)
login
;;
3)
# 输出退出信息并退出脚本
echo -e "\n退出中..."
exit 0
;;
*)
# 如果用户输入了无效的选择,则输出提示信息
echo -e "\n无效的选择。请输入1到3之间的数字。\n"
;;
esac
read -n1 -r -p "按任意键继续..."
done
#!/bin/bash
#===============================================
#
# FILE:user.sh
#
# USAGE:./user.sh
#
# DESCRIPTION:用户注册登录脚本,检查用户名、密码、手机号码和电子邮件地址
#
# OPTIONS: ---
# REQUIREMENTS:/etc/selfinfo 文件用于存储用户信息
# BUGS: ---
# NOTES: ---
# AUTHOR: mmy ,2176526290@qq.com
# ORGANIZATION:
# CREATED: 05/14/2024 20:14
# REVISION: ---
#=================================================
# 检查/etc/selfinfo文件是否存在,如果不存在则创建
# /etc/selfinfo文件持久化存储用户注册信息
if [ ! -f /etc/selfinfo ]; then
touch /etc/selfinfo
fi
# register 函数定义,用于用户注册流程
# 检查用户名、密码、手机号码、电子邮件地址的格式
register() {
# 读取用户输入的用户名,并提示用户输入时用户名必须以大写字母开头
read -p "请输入用户名(必须以大写字母开头): " username
# 检查用户名是否已存在
# 使用grep命令检查/etc/selfinfo文件中是否已存在以输入的用户名开头的行
# 如果存在,则输出提示信息并返回状态码1
if grep -q "^$username:" /etc/selfinfo; then
echo -e "\n用户名 '$username' 已存在,请选择其他用户名。\n"
return 1
fi
# 循环检查用户名格式,直到输入的用户名以大写字母开头
while ! [[ $username =~ ^[A-Z]$ ]]; do
read -p "$username无效的用户名格式。请重新输入用户名: " username
done
# 无限循环检查密码格式,直到输入的密码至少8个字符,且包含指定的特殊字符
while true; do
# 隐藏用户输入的密码,并设置密码格式要求
read -sp "请输入密码(至少8个字符,并且包含'&', '$', '_'中的至少一个): " password
echo " " # 输出一个空行以便区分密码输入和其他信息
# 检查密码是否满足条件
# 检查密码是否满足条件(至少8个字符,且包含指定的特殊字符)
# 如果满足条件,则输出密码设置成功的提示信息,并跳出循环
# 否则,提示用户密码格式无效并重新输入密码
if [[ ${#password} -ge 8 && "$password" =~ [\&\$\_] ]]; then
read -sp "密码设置成功! "
break # 如果密码满足条件,则跳出循环
else
echo -e "\n$password密码无效,请确保至少8个字符,并且包含'&', '$', '_'中的至少一个。\n"
fi
done
echo " "
# 读取用户输入的手机号码,并检查手机号码是否以139开头,且长度为11位
read -p "请输入手机号码(必须以139开头): " phone
# 检查手机号码是否已存在
# 使用grep检查手机号码是否已存在于 /etc/selfinfo 文件中
# 如果存在,则输出提示信息并返回状态码1
if grep -q "^[^:]*:[^:]*:$phone:" /etc/selfinfo; then
echo "手机号码 '$phone' 已存在,请选择其他手机号码。"
return 1
fi
# 如果手机号码格式正确且不存在,则继续后续操作
echo "手机号码 '$phone' 可用。"
# 循环检查手机号码格式,直到满足条件
while ! [[ $phone =~ ^139[0-9]{8}$ ]]; do
read -p "$phone无效的手机号码。请重新输入手机号码: " phone
done
# 读取用户输入的电子邮件地址,并检查电子邮件地址是否以数字开头,并以@qq.com结尾
read -p "请输入电子邮件地址(必须以数字开头,并以 @qq.com 结尾): " email
# 检查电子邮件地址是否已存在
# 使用grep检查电子邮件地址是否已存在于 /etc/selfinfo 文件中
# 如果存在,则输出提示信息并返回状态码1
if grep -qF "$email" /etc/selfinfo; then
echo "电子邮件地址 '$email' 已存在,请选择其他电子邮件地址。"
return 1
fi
# 如果电子邮件地址不存在,则继续后续操作
echo "电子邮件地址 '$email' 可用。"
# 循环检查电子邮件地址格式,直到满足条件
while ! [[ $email =~ ^[0-9].*@qq.com$ ]]; do
read -p "$email无效的电子邮件地址。请重新输入电子邮件地址: " email
done
# 将用户信息(用户名、密码、手机号码、电子邮件地址)追加到/etc/selfinfo文件中
echo "$username:$password:$phone:$email" >> /etc/selfinfo
# 输出用户注册成功的提示信息
echo -e "\n用户注册成功!\n"
}
# login 函数定义,用于用户登录流程
# 检查当前读取的用户名和密码是否与用户输入的用户名和密码匹配
login() {
# 读取用户输入的用户名
read -p "请输入用户名: " username
# 隐藏用户输入的密码
read -sp "请输入密码: " password
# 使用while循环遍历/etc/selfinfo文件,该文件应该包含用户名、密码、电话号码和电子邮件信息,每行一条记录,字段之间用冒号(:)分隔
while IFS=":" read -r u p phone email ; do
# 检查当前读取的用户名和密码是否与用户输入的用户名和密码匹配
if [[ $u == "$username" && $p == "$password" ]]; then
# 如果匹配,输出登录成功的消息
echo -e "\n登录成功!欢迎,$username!\n"
# 运行cmatrix命令
cmatrix
# 退出函数并返回状态码0,表示成功
return 0
fi
# done关键字标志着while循环的结束,< "/etc/selfinfo"表示从/etc/selfinfo文件中读取数据
done < "/etc/selfinfo"
# 如果循环结束后仍未找到匹配的用户名和密码,则输出登录失败的消息
echo -e "\n登录失败。用户名、密码不匹配。\n"
# 退出函数并返回状态码1,表示失败
return 1
}
# 无限循环,直到用户选择退出
while true; do
# 清屏,以便用户看到新的菜单
clear
# 输出欢迎信息和菜单选项
echo -e "Welcome"
echo "==========="
echo " "
echo "1. 注册" # 提供注册选项
echo "2. 登录" # 提供登录选项
echo "3. 退出" # 提供退出程序选项
echo " "
echo "==========="
# 读取用户的选择
read -p "请输入您的选择: " choice
# 使用case语句根据用户的选择执行不同的操作
case $choice in
1)
# 调用注册函数,进行用户注册流程
register
;;
2)
# 调用登录函数,进行用户登录流程
login
;;
3)
# 输出退出信息,并退出程序
echo -e "\n退出中..."
exit 0 # 退出脚本,返回状态码0表示成功
;;
*)
# 如果用户输入的不是1到3之间的数字,则输出错误提示
echo -e "\n无效的选择。请输入1到3之间的数字。\n"
;;
esac
# 等待用户按任意键后继续显示菜单
read -n1 -r -p "按任意键继续..."
done
测试
创建以上脚本,赋予执行权限后bash执行
输入选项1,注册用户“LUU”,按要求创建该用户的密码,手机号码及电子邮箱地址后显示注册成功
输入选项2,输入正确的用户名,密码,电话号码及电子邮箱地址执行登录,显示该用户登录成功(如图一)!错误则如图二
输入选项3则退出
创建完“LUU”后,该用户信息已被保存在/etc/secfinfe文件中,再次创建该用户会显示该用户已存在,提示创建其他新用户。
错误测试
1)用户名首字母未大写
2)所创8位数密码不含“$”,“&”,“-”中的任意一个
3)手机号未以139开头
4)qq.com的邮箱未以数字开头
cmatrix命令屏保显示
在编译 cmatrix 之前,你需要安装一些必要的依赖包,输入命令行:sudo yum install -y ncurses-devel gcc自动安装ncurses-devel和gcc软件包。
sudo yum install -y ncurses-devel gcc
使用 wget 工具来从从 SourceForge 网站下载一个cmatrix 项目的 1.2a 版本的一个 gzip 压缩的 tar 文件wget -q https://jaist.dl.sourceforge.net/project/cmatrix/cmatrix/1.2a/cmatrix-1.2a.tar.gz
wget -q https://jaist.dl.sourceforge.net/project/cmatrix/cmatrix/1.2a/cmatrix-1.2a.tar.gz
下载完成后,输入“tar -zxvf cmatrix-1.2a.tar.gz
”命令解压缩源代码包
tar -zxvf cmatrix-1.2a.tar.gz
cd cmatrix-1.2a/进入解压缩后的目录,并开始编译和安装过程
安装完成后,你可以输入命令行:/opt/cmatrix/bin/cmatrix -V
检查 cmatrix 的版本输入命令“echo 'export PATH=/opt/cmatrix/bin:$PATH' >> ~/.bashrc”将 cmatrix 的安装目录添加到 PATH 环境变量中后,输入命令行:source ~/.bashrc读取并执行指定文件,安装完成后,你可以通过简单地输入 cmatrix 来运行程序。即可实现《黑客帝国》中的数字雨效果。
/opt/cmatrix/bin/cmatrix -V
echo 'export PATH=/opt/cmatrix/bin:$PATH' >> ~/.bashrc
这将启动数字雨动画,并在终端窗口中显示。cmatrix 的一些常见选项包括:
--no-colors:不使用颜色。
--no-rain:不显示雨效果。
--matrix:显示一个静态的字符矩阵而不是动画。
--display-time:设置字符在屏幕上显示的时间(以百分之一秒为单位)。
--speed:设置动画的速度。
例如,如果你想以较快的速度运行 cmatrix,可以使用以下命令:
cmatrix --speed 1
要停止 cmatrix 动画,可以按 q 键或使用鼠标点击终端窗口关闭。
注意!
cmatrix 是一个娱乐性的工具,它不会提供任何实际的计算或数据处理功能。它主要用于视觉效果,以显示系统正在“忙碌”工作,尤其是在执行实际任务时作为背景。
如果你在安装或运行 cmatrix 时遇到问题,可以检查 CentOS 的软件仓库是否有可用的更新,或者查看 cmatrix 的手册页(通过运行 man cmatrix)以获取更多帮助和选项。将cmatrix 命令添加至注册及登录用户的Shell脚本中,登录成功后即可显示出《黑客帝国》中的数字雨效果。
通过用户注册及登录实验,可以深入理解Shell脚本的编写和用户权限管理的概念。实验不仅提高了Shell编程技能,还增强了系统安全意识和编程规范意识。
遇到的问题及解决方案
安全性问题:明文存储密码是不安全的。可以使用openssl等工具对密码进行哈希处理,并存储哈希值而不是明文密码。
用户输入验证:需要确保用户输入符合规范。可以使用正则表达式进行验证。
脚本复杂性:随着功能的增加,脚本可能会变得复杂。可以考虑使用函数来模块化代码,提高可读性和维护性。
改进建议
增强安全性:使用更安全的密码存储和验证方法,如哈希和加盐哈希。
增加功能:例如,支持密码重置、用户信息修改等功能。
优化用户体验:改进用户界面,提供更友好的错误提示和帮助信息。
考虑并发和性能:如果系统需要处理大量用户请求,需要考虑并发和性能问题,并采取相应的优化措施。