本篇文章几乎涵盖了绝大部分的Shell语法练习,用一个个实战练习,巩固Shell的学习,话不多说,直接开始。
一、基础
练习1:按照时间生成文件"2018-05-22.log"将每天的磁盘使用状态写入到对应日期的文件
[root@Shell test]# cat disk_status_backup.sh #!/bin/bash name=`date +%F` /bin/df -h > /tmp/"$name".log [root@Shell test]# sh disk_status_backup.sh [root@Shell test]# cat /tmp/2023-05-17.log Filesystem Size Used Avail Use% Mounted on devtmpfs 476M 0 476M 0% /dev tmpfs 487M 0 487M 0% /dev/shm tmpfs 487M 14M 473M 3% /run tmpfs 487M 0 487M 0% /sys/fs/cgroup /dev/sda3 19G 2.0G 17G 11% / /dev/sda1 197M 110M 88M 56% /boot tmpfs 98M 0 98M 0% /run/user/0 [root@Shell test]# crontab -l 59 23 * * * sh /server/scripts/test/disk_status_backup.sh • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16
练习2:统计Nginx日志中每个IP的访问量有多少,日志格式如下
192.168.56.1 - - [21/May/2018:20:44:06 -0400] "GET /index.html HTTP/1.0" 404 169 "-" "ApacheBench/2.3" "-"/code/index.html [root@Shell test]# cat count_nginx_ip.sh #!/bin/bash cat /var/log/nginx/access.log-20230506|awk '{print $1}'|sort -rn|uniq -c [root@Shell test]# sh count_nginx_ip.sh 207 172.16.1.5 • 1 • 2 • 3 • 4 • 5 • 6 • 7
练习3:写一个脚本计算一下Linux系统所有进程占用内存的大小的和
%MEM列是进程占用物理内存的百分比。可以通过查看该值来了解进程所使用的物理内存比例大小。
VSZ(Virtual Memory Size)是虚拟内存的大小,表示进程所使用的虚拟内存空间大小。
RSS(Resident Set Size)是进程实际使用的物理内存大小,即占用的内存数,单位为KB。
我们求RSS的和
[root@Shell test]# cat process_occupies_memory_size.sh #!/bin/bash ps axu|awk 'NR!=1{print $6}'|grep -v ^0$|awk '{sum+= $1}END{print sum}' [root@Shell test]# sh process_occupies_memory_size.sh 2038676 • 1 • 2 • 3 • 4 • 5
练习4:在/backup下创建10个.txt的文件,找到/backup目录下所有后缀名是.txt的文件
批量修改txt为txt.bak,把所有的.bak文件内打包压缩为123.tar.gz,批量还原文件的名字,把增加的.bak删除掉
[root@Shell test]# cat file_handle.sh #!/bin/bash for i in `ls /backup` do cp /backup/"$i" /backup/"$i".bak done tar zcvf /backup/123.tar.gz /backup/*.txt.bak &> /dev/null rm -rf /backup/*.txt.bak [root@Shell test]# sh file_handle.sh [root@Shell test]# ls /backup/ 10.txt 1.txt 3.txt 5.txt 7.txt 9.txt 123.tar.gz 2.txt 4.txt 6.txt 8.txt [root@Shell test]# tar tf /backup/123.tar.gz backup/10.txt.bak backup/1.txt.bak backup/2.txt.bak backup/3.txt.bak backup/4.txt.bak backup/5.txt.bak backup/6.txt.bak backup/7.txt.bak backup/8.txt.bak backup/9.txt.bak • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23
二、计算
练习1:输入两个整数计算这两个整数的相加,相减,相乘,相除,求余的结果。
[root@Shell test]# cat jisuan.sh #/bin/bash num1=$1 num2=$2 echo "两数相加为:$num1 + $num2 = $(awk "BEGIN{print $num1+$num2}")" echo "两数相减为:$num1 - $num2 = $(awk "BEGIN{print $num1-$num2}")" echo "两数相乘为:$num1 * $num2 = $(awk "BEGIN{print $num1*$num2}")" echo "两数相除为:$num1 / $num2 = $(awk "BEGIN{print $num1/$num2}")" echo "两数求余为:$num1 % $num2 = $(awk "BEGIN{print $num1%$num2}")" [root@Shell test]# sh jisuan.sh 9 3 两数相加为:9 + 3 = 12 两数相减为:9 - 3 = 6 两数相乘为:9 * 3 = 27 两数相除为:9 / 3 = 3 两数求余为:9 % 3 = 0 • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16
练习2:把一个文本文档的前五行中包含字母的行删掉,同时把6到10行中全部字母删掉
[root@Shell test]# cat delete.sh #!/bin/bash # 指定待处理的文本文档路径 file_path="your_file_path.txt" # 临时文件路径 temp_file="temp.txt" # 删除前五行中包含字母的行 sed '1,5 { /[a-zA-Z]/d }' "$file_path" > "$temp_file" # 删除6到10行中的所有字母 sed '6,10 s/[a-zA-Z]//g' "$temp_file" > "$file_path" # 删除临时文件 rm "$temp_file" • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17
练习3:打印下面这句话中字母数小于3的单词,I am koten I am 18
[root@Shell test]# cat print.sh #!/bin/bash sentence="I am koten I am 18" echo "$sentence" | awk '{ for(i=1; i<=NF; i++) { if (length($i) < 3) print $i } }' • 1 • 2 • 3 • 4 • 5 • 6
练习4:写一个Shell,看看linux系统中是否有自定义用户(普通用户),若是有,一共有几个?
[root@Shell test]# cat user.sh #!/bin/bash # 获取系统中普通用户的数量 user_count=$(awk -F: '$3>=1000 && $1!="nobody" {print $1}' /etc/passwd | wc -l) if [ $user_count -gt 0 ]; then echo "系统中存在 $user_count 个自定义普通用户。" else echo "系统中没有自定义普通用户。" fi • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11
练习5:写一个Shell脚本来看看你使用的最多的命令是哪些,列出你最常用的命令top10
[root@Shell test]# cat history_cmd.sh #!/bin/bash # 指定要统计的shell历史文件路径 history_file=~/.bash_history # 统计命令使用频率,并获取前10个最常用的命令 top_commands=$(cat "$history_file" | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10) echo "您使用最多的命令 Top 10:" echo "$top_commands" • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11
练习6:编写一个脚本,计算100以内所有能被3整除数字的和
[root@Shell test]# cat 3.sh #!/bin/bash sum=0 # 循环遍历1到100之间的数字 for ((num=1; num<=100; num++)) do # 判断数字是否能被3整除 if [ $((num % 3)) -eq 0 ]; then sum=$((sum + num)) fi done echo "100以内所有能被3整除的数字的和为:$sum" • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15
三、判断
练习1:将下面的条件表达式,写成if条件语句
[ -f /etc/hosts ] && echo !
[root@Shell test]# cat if.sh #!/bin/bash if [ -f /etc/hosts ]; then echo "!" fi • 1 • 2 • 3 • 4 • 5 • 6
练习2:写一个脚本,实现判断10.0.0.0/24网络里,当前在线用户的IP有哪些
[root@Shell test]# cat ping.sh #!/bin/bash network="10.0.0" # 循环遍历IP地址范围内的所有地址 for ((i=1; i<=255; i++)) do ip="${network}.${i}" # 使用ping命令检查IP地址是否在线 ping -c 1 -w 1 "$ip" > /dev/null 2>&1 # 检查ping命令的返回值,如果为0则表示IP地址在线 if [ $? -eq 0 ]; then echo "IP地址 $ip 在线" fi done • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18
练习3:用shell处理以下内容,按单词出现频率降序排序,按字母出现频率降序排序。
the squid project provides a number of resources toassist users design,implement and support squid installations. Please browsethe documentation and support sections for more infomation
[root@Shell test]# cat sort.sh #!/bin/bash content="the squid project provides a number of resources to assist users design, implement and support squid installations. Please browse the documentation and support sections for more information." # 按单词出现频率降序排序 word_frequency=$(echo "$content" | awk '{ for(i=1; i<=NF; i++) { count[$i]++ } } END { for(word in count) { print count[word], word } }' | sort -rn) echo "按单词出现频率降序排序:" echo "$word_frequency" echo # 按字母出现频率降序排序 letter_frequency=$(echo "$content" | grep -o . | grep -v '[. ]' | sort | uniq -c | sort -rn) echo "按字母出现频率降序排序:" echo "$letter_frequency" • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18
练习4:使用 ps aux 查看系统进程发现有100个test.sh脚本正在运行,如何杀死所有的test.sh
[root@Shell test]# cat kill.sh ps aux | grep test.sh | awk '{print $2}' | xargs kill