核心内容摘要
基于Java EE的高校排课系统(11859)
Shell内置命令
1 内置命令介绍Shell 内置命令就是由Bash Shell自身提供的命令而不是文件系统中的可执行文件。
内置命令无需触发磁盘I/O也无需创建新进程执行速度更快相当于调用当前Shell进程的一个函数减少上下文切换。
可使用type命令判断一个命令是否为内置命令语法type 命令[rootnode1 ~]# type cdcdis a shellbuiltin# 内置命令[rootnode1 ~]# type ifconfigifconfigis /usr/sbin/ifconfig# 可执行脚本文件[rootnode1 ~]# type crontabcrontabis /usr/bin/crontab# 可执行脚本文件
2 常用内置命令列表alias为指定命令定义一个别名bg将作业以后台模式运行bind将键盘序列绑定到一个readline函数或宏break退出 for、while、select 或 until 循环builtin执行指定的shell内建命令caller返回活动子函数调用的上下文cd将当前目录切换为指定的目录command执行指定的命令无需进行通常的shell查找compgen为指定单词生成可能的补全匹配complete显示指定的单词是如何补全的compopt修改指定单词的补全选项continue继续执行for、while、select或until循环的下一次迭代declare声明一个变量或变量类型dirs显示当前存储目录的列表disown从进程作业表中删除指定的作业echo将指定字符串输出到STDOUTenable启用或禁用指定的内建shell命令eval将指定的参数拼接成一个命令然后执行该命令exec用指定命令替换shell进程exit强制shell以指定的退出状态码退出export设置子shell进程可用的变量fc从历史记录中选择命令列表fg将作业以前台模式运行getopts分析指定的位置参数hash查找并记住指定命令的全路径名help显示帮助文件history显示命令历史记录jobs列出活动作业kill向指定的进程ID(PID)发送一个系统信号let计算一个数学表达式中的每个参数local在函数中创建一个作用域受限的变量logout退出登录shellmapfile从STDIN读取数据行并将其加入索引数组popd从目录栈中删除记录printf使用格式化字符串显示文本pushd向目录栈添加一个目录pwd显示当前工作目录的路径名read从STDIN读取一行数据并将其赋给一个变量readarray从STDIN读取数据行并将其放入索引数组在这里插入代码片
3 高频内置命令详解
1.
1alias设置命令别名alias用于给命令创建别名可将复杂命令简化提升工作效率不带任何参数时会显示当前Shell进程中的所有别名列表。
[rootnode1 ~]# aliasaliascpcp -ialiasegrepegrep --colorautoaliasfgrepfgrep --colorautoaliasgrepgrep --colorautoaliasl.ls -d .* --colorautoaliasllls -l --colorautoaliaslsls --colorautoaliasmvmv -ialiasrmrm -ialiaswhichalias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde上述为系统默认别名例如ll与ls -l功能完全一致就是因为设置了别名。
语法说明定义别名alias 别名命令单引号、双引号均可删除指定别名unalias 别名删除所有别名unalias -a提示上述删除操作均为临时生效仅作用于当前Shell环境若需永久删除需手动修改对应的配置文件。
实操案例# 定义别名psList对应命令ps -aux[rootnode1 ~]# alias psListps -aux# 查看别名确认定义成功[rootnode1 ~]# alias# 执行别名等同于执行ps -aux[rootnode1 ~]# psList# 删除别名psList[rootnode1 ~]# unalias psList
1.
2 echo输出字符串echo是最常用的内置命令用于在终端输出字符串默认在末尾添加换行符核心可实现不换行输出和转义字符解析。
语法说明默认换行输出echo 字符串不换行输出echo -n 字符串解析转义字符echo -e 字符串含转义字符-e参数用于启用转义解析常用转义字符\n换行\c清除结尾的换行实操案例# 默认输出自动换行[rootnode1 ~]# echo hello worldhello world# 不换行输出[rootnode1 ~]# echo -n hello worldhello world[rootnode1 ~]## 未加-e转义字符不生效[rootnode1 ~]# echo hello\nworldhello\nworld# 加-e解析换行转义字符[rootnode1 ~]# echo -e hello\nworldhello world
1.
3 read读取控制台输入read用于从标准输入默认终端控制台读取数据并赋值给变量支持设置提示符、读取长度、静默模式和超时时间也可通过重定向从文件读取数据。
基本语法read (选项) (参数)选项说明-p prompt指定读取值时的提示符-n num读取num个字符无需按回车确认-s静默模式不显示输入的字符适合输入密码-t seconds设置等待时间秒超时自动退出参数说明变量用于存储读取数据的变量名实操案例# 案例110秒内读取控制台输入的名称并输出欢迎信息[rootnode1 scripts]# vim read_test.sh#!/bin/bashread-t10-p请输入您的芳名nameechowelcome,$name# 执行脚本[rootnode1 scripts]# ./read_test.sh请输入您的芳名rapden welcome,rapden# 案例2读取1个字符用于确认操作[rootnode1 scripts]# vim read
sh#!/bin/bashread-n1-p您确定要删除数据吗请输入y/n:charprintf\n# 换行避免光标紧跟输入内容echo您输入的字符${char}# 执行脚本[rootnode1 scripts]# ./read
sh您确定要删除数据吗请输入y/n:y 您输入的字符y
1.
4 exit退出Shell进程exit用于退出当前Shell环境进程可返回指定状态码通过$?变量可获取该状态码用于判断命令或脚本的执行结果。
语法说明正常退出exit默认返回状态码0代表执行成功错误退出exit 非0数字数字范围0~255代表执行失败不同数字可区分错误类型应用场景主动结束当前Shell进程脚本执行出错时返回对应状态码便于定位错误如1代表文件不存在2代表权限不足
1.
5 declare设置变量属性declare用于声明Shell变量、设置变量属性也可显示Shell变量与函数与set命令效果一致还可创建关联数组。
语法说明declare [/-] [aArxif] [变量名称设置值]/--用于设置变量属性用于取消变量属性-a设置为普通索引数组-A设置为key-value关联数组仅Bash支持-r设置为只读变量等同于readonly-x设置为全局变量等同于export-i设置为整型变量-f设置为函数变量declare -f查询所有函数定义declare -F查询所有函数名称实操案例# 案例1设置整型变量[rootnode1 scripts]# declare -i age20[rootnode1 scripts]# echo $age20[rootnode1 scripts]# ageabc # 非数值赋值整型变量会显示为0[rootnode1 scripts]# echo $age0[rootnode1 scripts]# declare i age # 取消整型属性[rootnode1 scripts]# ageabc # 可正常赋值字符串[rootnode1 scripts]# echo $ageabc[rootnode1 scripts]# declare -r age # 设置为只读[rootnode1 scripts]# age123 # 无法修改提示错误-bash: age:readonlyvariable# 案例2创建关联数组键值对数组[rootnode1 scripts]# declare -A student([name]rapden [age]20 [gender]male)# 获取指定键的值[rootnode1 scripts]# echo ${student[name]}rapden# 获取所有值[rootnode1 scripts]# echo ${student[*]}rapden20male[rootnode1 scripts]# echo ${student[]}rapden20male
函数Shell函数用于将一系列命令组合在一起实现代码复用简化脚本编写与维护分为系统函数和自定义函数两类。
1 系统函数
2.
1 basename提取文件名basename用于删除路径中所有前缀包括最后一个/提取文件名支持去除指定后缀。
基本语法basename [string / pathname] [suffix]string / pathname文件路径或字符串suffix可选指定后缀若添加则去除文件名的该后缀实操案例# 提取文件名称含后缀[rootnode1 scripts]# basename /root/scripts/hello.shhello.sh# 提取文件名称去除.sh后缀[rootnode1 scripts]# basename /root/scripts/hello.sh .shhello
2.
2 dirname提取文件路径dirname用于从文件绝对路径中去除文件名提取剩余的目录路径。
基本语法dirname 文件绝对路径实操案例# 提取hello.sh文件的目录路径[rootnode1 scripts]# dirname /root/scripts/hello.sh/root/scripts
2 自定义函数
2.
1 基本语法[function]funname[()]{Action;# 函数执行的命令[return int;]# 可选返回状态码0~255}function可选用于声明函数可省略funname函数名遵循变量命名规则字母、数字、下划线不数字开头return可选用于返回状态码若省略默认以最后一条命令的执行结果作为返回值
2.
2 经验技巧函数必须在调用前声明Shell脚本逐行执行不提前编译函数返回值只能通过$?变量获取return后跟数值范围为0~255函数参数通过$1~$n获取与脚本参数用法一致$#获取参数个数
2.
3 实操案例需求编写函数计算两个输入参数的和并输出结果及和的平方。
[rootnode1 scripts]# vim func_test.sh#!/bin/bash# 声明函数add计算两个数的和functionadd(){s$[$1$2]# $1获取第一个参数$2获取第二个参数echo$s# 输出和用于后续获取结果}# 读取用户输入的两个整数read-p请输入第一个整数aread-p请输入第二个整数b# 调用函数将结果赋值给sum变量sum$(add$a $b)# 输出结果echo和$sumecho和的平方$[$sum*$sum]# 执行脚本[rootnode1 scripts]# ./func_test.sh请输入第一个整数5 请输入第二个整数8 和13 和的平方169
正则表达式入门正则表达式是用于描述、匹配一系列符合特定语法规则的字符串的工具常用于文本检索、替换。
Linux中grep、sed、awk等文本处理工具均支持正则表达式匹配。
1 常规匹配不包含特殊字符的正则表达式直接匹配自身对应的字符串例如匹配包含“atguigu”的行[atguiguhadoop101 shells]$cat/etc/passwd|grepatguigu
2 常用特殊字符
3.
1 锚点匹配^匹配一行的开头$匹配一行的结尾# 匹配以a开头的行[rootnode1 ~]# cat /etc/passwd | grep ^aadm:x:3:4:adm:/var/adm:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin# 匹配以nologin结尾的行[rootnode1 ~]# cat /etc/passwd | grep nologin$# 匹配空行^匹配开头$匹配结尾中间无字符[rootnode1 ~]# cat /etc/passwd | grep ^$
3.
2 任意字符匹配.匹配任意一个字符除换行符外*与前一个字符连用匹配前一个字符0次或多次.*匹配任意字符任意次即匹配所有内容# 匹配包含r两个任意字符t的行如rabt、rxt、root等[rootnode1 scripts]# cat daily_archive.sh | grep r..tDEST/root/archive/$FILE# 匹配包含rot的行如rt、rot、root、rooot等[rootnode1 scripts]# cat /etc/passwd | grep ro*troot:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin
3.
3 字符区间匹配[]匹配某个范围内的一个字符支持指定单个字符、连续区间。
[6,8]匹配6或8[
]匹配一个0~9的数字[a-z]匹配一个a~z的小写字母[a-c,e-f]匹配a~c或e~f之间的任意一个字符[
]*匹配任意长度的数字字符串实操案例匹配手机号手机号规则以1开头第二位为
后续9位为
共11位。
# 使用-E参数启用扩展正则支持{}匹配固定次数[rootnode1 scripts]# echo 15623456789 | grep -E ^1[
][
]{9}$15623456789# 匹配成功[rootnode1 scripts]# echo 12623456789 | grep -E ^1[
][
]{9}$# 匹配失败无输出
文本处理工具
1 cut文本切割工具cut用于从文件或标准输入中剪切字节、字符或字段并输出结果默认以制表符\t为分隔符。
4.
1 基本用法cut[选项参数]filename
4.
2 选项参数说明选项参数功能-f列号提取指定列多个列用逗号分隔连续列用短横线连接-d指定分隔符默认是制表符\t-c按字符切割后续跟数字表示提取第几个字符
4.
3 实操案例#
准备测试数据[rootnode1 scripts]# vim cut.txtdong shen guan zhen wo wo lai lai le le#
以空格为分隔符提取第一列[rootnode1 scripts]# cut -d -f 1 cut.txtdong guan wo lai le#
以空格为分隔符提取第
三列[rootnode1 scripts]# cut -d -f 2,3 cut.txtshen zhen wo lai le#
提取PATH变量中第3个:开始后的所有路径[rootnode1 scripts]# echo $PATH/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/atguigu/.local/bin:/home/atguigu/bin[rootnode1 scripts]# echo $PATH | cut -d : -f 3-/usr/local/sbin:/usr/sbin:/home/atguigu/.local/bin:/home/atguigu/bin#
提取IP地址以ens33网卡为例[rootnode1 scripts]# ifconfig ens33 | grep netmaskinet
192.
168.
2
101 netmask
255.
255.
2
0 broadcast
192.
168.
2
255[rootnode1 scripts]# ifconfig ens33 | grep netmask | cut -d -f
10192.
168.
200.
1
2 awk文本分析工具awk是强大的文本分析工具逐行读取文件内容以空格为默认分隔符将每行切片再对切片后的内容进行分析处理支持条件匹配、数值计算、内置变量等功能。
4.
1 基本用法awk[选项参数]/pattern/{action1} /pattern2/{action2}...filenamepattern匹配模式awk会查找符合该模式的行action匹配成功后执行的命令如打印、计算
4.
2 选项参数说明选项参数功能-F指定输入文件的分隔符-v赋值一个用户定义变量
4.
3 实操案例#
准备测试数据复制系统passwd文件[rootnode1 scripts]# cp /etc/passwd ./# passwd文件格式用户名:密码:用户id:组id:注释:家目录:shell解析器#
匹配以root开头的行输出第7列shell解析器[rootnode1 scripts]# awk -F : /^root/{print $7} passwd/bin/bash#
匹配以root开头的行输出第1列和第7列用逗号分隔[rootnode1 scripts]# awk -F : /^root/{print $1,$7} passwdroot,/bin/bash#
输出所有行的第1列和第7列添加列名和结尾标识[rootnode1 scripts]# awk -F : BEGIN{print user shell}{print $1,$7} END{print end of file} passwduser shell root,/bin/bash bin,/sbin/nologin daemon,/sbin/nologin... end offile#
将用户id第3列加1后输出[rootnode1 scripts]# awk -v i1 -F : {print $3i} passwd
..#
统计文件名、每行的行号和列数[rootnode1 scripts]# awk -F : {print filename: FILENAME ,linenum: NR ,col: NF } passwdfilename:passwd,linenum:1,col:7 filename:passwd,linenum:2,col:
..#
查找ifconfig输出中的空行行号[rootnode1 scripts]# ifconfig | awk /^$/{print NR}91827#
提取所有IP地址[rootnode1 scripts]# ifconfig | awk /netmask/{print $2}
172.
17.
0.
1192.
168.
200.
101127.
0.
0.
14.
4 awk内置变量变量说明FILENAME当前处理的文件名NR已读取的记录数行号NF当前行切割后的列数
综合应用案例
1 归档文件每日自动备份需求说明实现每天对指定目录归档备份输入一个目录名称末尾不带/将目录下所有文件按天归档压缩归档文件名附加日期保存到/root/archive目录下。
核心工具tar归档压缩-c归档-z压缩生成.tar.gz格式文件。
脚本实现[rootnode1 scripts]# vim daily_archive.sh#!/bin/bash# 功能每日归档指定目录保存到/root/archive# 步骤1判断输入参数个数是否为1if[$#-ne1]thenecho参数个数错误应该输入一个参数作为归档目录名exit1# 错误退出状态码1代表参数错误fi# 步骤2判断输入的目录是否存在if[-d$1]thenecho目录存在开始准备归档...elseecho目录不存在exit2# 错误退出状态码2代表目录不存在fi# 步骤3获取目录名称和绝对路径DIR_NAME$(basename$
# 提取目录名DIR_PATH$(cd$(dirname $
;pwd)# 获取目录绝对路径# 步骤4获取当前日期格式年月日如251022DATE$(date%y%m%d)# 步骤5定义归档文件名和目标路径FILEarchive_${DIR_NAME}_${DATE}.tar.gzDEST/root/archive# 若目标目录不存在创建目录if[!-d$DEST]thenmkdir-p$DESTfi# 步骤6执行归档压缩echo开始归档....tar-czf$DEST/$FILE$DIR_PATH/$DIR_NAME# 步骤7判断归档是否成功if[$?-eq0]thenecho归档成功echo归档文件名为$DEST/$FILEelseecho归档出现问题exit3# 错误退出状态码3代表归档失败fiexit0# 正常退出脚本测试与定时任务# 执行脚本测试归档归档../scripts目录[rootnode1 scripts]# ./daily_archive.sh ../scripts目录存在开始准备归档... 开始归档....tar: Removing leading / from member names 归档成功 归档文件名为/root/archive/archive_scripts_
tar.gz# 设置定时任务每天凌晨2点自动归档/root/scripts目录[rootnode1 scripts]# crontab -e# 添加如下内容0 2 * * * 表示每天凌晨2点执行02* * * /root/scripts/daily_archive.sh /root/scripts# 查看定时任务[rootnode1 scripts]# crontab -l02* * * /root/scripts/daily_archive.sh /root/scripts
2 发送消息快速给指定用户发消息需求说明实现向指定用户快速发送消息输入用户名作为第一个参数后续为要发送的消息。
需检测用户是否登录、用户是否开启消息功能、消息是否为空。
核心工具mesg查看/开启消息功能、write发送消息。
脚本实现[rootnode1 scripts]# vim send_msg.sh#!/bin/bash# 功能向指定用户发送消息需检测用户状态和消息内容# 步骤1判断参数个数是否至少为2用户名消息if[$#-lt2]thenecho参数错误用法$0用户名 消息内容exit1fi# 步骤2提取用户名和消息内容USER$1shift# 移除第一个参数用户名剩余参数作为消息MSG$*# 步骤3检测用户是否登录# 查看当前登录用户过滤目标用户who | grep -w 精确匹配用户名if!who|grep-w$USER/dev/nullthenecho错误用户$USER未登录系统exit2fi# 步骤4检测用户是否开启消息功能mesg查看允许消息输出为y# 切换到目标用户执行mesg捕获输出结果MESG_STATUS$(su-$USER-cmesg2/dev/null|awk{print $1})if[$MESG_STATUS!y]thenecho错误用户$USER未开启消息接收功能exit3fi# 步骤5检测消息是否为空if[-z$MSG]thenecho错误消息内容不能为空exit4fi# 步骤6发送消息write 用户名 终端消息通过echo传入# 获取用户登录的终端who | grep -w $USER | awk {print $2}取第一个终端TERMINAL$(who|grep-w$USER|awk{print $2}|head-n