Linux实战——Shell编程练习(更新12题)
1.公钥批量分发
shell 实现 100 台服务器的公钥的批量分发;LLD 规划:100 台服务器 ip 为:192.168.42.101-201,root 密码:123456。
#远程机器的用户名和密码 password=123456 username=root #将本机的公钥复制到远程机器的authorized_keys文件中 main(){ sshpass -p $password ssh-copy-id -o StrictHostKeyChecking=no $1 >/dev/null 2>&1 if [ $? -eq 0 ] then echo "192.168.42.$1 is successful..." fi } #检查sshpass工具是否安装 basecheck(){ which sshpass >/dev/null 2>&1 if [ $? -ne 0 ] then yum install sshpass -y >/dev/null 2>&1 fi } #检查网络是否畅通,若通畅则发送ssh公钥 netcheck(){ for j in {101..201} do ping -c 1 192.168.42.$j >/dev/null 2>&1 if [ $? -eq 0 ] then main $j else echo "192.168.42.$j 网络不通畅..." fi done } basecheck netcheck
2.网址中的域名统计
处理以下文件内容,将域名取出并进行计数排序。
http://www.baidu.com/index.html http://www.baidu.com/1.html http://post.baidu.com/index.html http://mp3.baidu.com/index.html http://www.baidu.com/3.html http://post.baidu.com/2.html
得到如下结果:
域名出现的次数 域名 2 www.baidu.com 2 post.baidu.com 1 mp3.baidu.com
cat <<EOF 域名出现的次数 域名 EOF array=( "http://www.baidu.com/index.html" "http://www.baidu.com/1.html" "http://post.baidu.com/index.html" "http://mp3.baidu.com/index.html" "http://www.baidu.com/3.html" "http://post.baidu.com/2.html" ) #检查临时域名文件是否存在,存在则删除 check(){ test -f yuming.txt if [ $? -eq 0 ] then rm -rf yuming.txt fi } #域名统计处理及结果输出 operate(){ for var in ${array[@]} do echo $var >> yuming.txt done awk -F ‘/‘ ‘{print $3}‘ yuming.txt |sort -r|uniq -c } check operate check
其他方法
cut -d / -f3 file.txt |sort -r |uniq -c awk -F "/"‘{S[$3]=S[$3]+1}END{for(k in S) print k,S[k]}‘ file.txt|sort -r sed -r ‘s#http://(.*)/.*#\1#g‘ file.txt |sort -r|uniq -c
3.shell+定时计划任务:归档备份
设计一个 shell 程序,在每天凌晨压缩打包/etc 目录下的所有内容,存放在/root/bak 目录里,且文件名为如下形式 yymmdd_etc.tar.gz(yy 为年,mm 为月,dd 为日),该目录保存 7 天内容;Shell 程序 fileback 存放在/usr/bin 目录下。
day="`date +%Y%m%d`" dir=/root/bak backupdir="`date +%Y%m%d`_etc.tar.gz" #查看/root/bak目录是否存在,如果不存在,则创建目录 checkbak(){ if [ ! -e $dir ] then mkdir $dir fi } #压缩打包/etc目录下,存放在/root/bak目录里 backup(){ tar -zcvf /root/bak/$backupdir /etc/ > /dev/null 2>&1 echo "$backupdir 压缩打包成功 successful" } #清除7天前的过期文件 clean(){ find $dir -mtime +7 -exec rm -rf {} \; if [ $? -eq 0 ] then echo "过期数据清除成功 successful" else echo "$day 过期数据清理失败 error,请及时关注" fi } checkbak backup clean
4.shell开发运维管理工具(1)
shell 开发运维管理工具,要求:用户交互,当用户输入菜单号时,打印相关内容。
菜单 1. 磁盘分区 2. CPU 负载 3. 剩余内存 4. 退出 输入:1 输出:(主机名,系统版本,分区情况) hostname: system:系统版本 ---------分区一-----------(分区变量输出) path:分区一 size:大小 file_os:分区文件系统类型 mount_on:分区挂载点 ----------分区二---------- path:分区二 size:大小 file_os:分区文件系统类型 mount_on:分区挂载点 输入:2 输出: 1 分钟平均负载: 5 分钟平均负载: 15 分钟平均负载: 输入:3 输出: 目前可用内存: 可用 Swap 分区: 输入:4 输出: Bey…
cat <<EOF --------------------------- 1.磁盘分区 2.CPU负载 3.剩余内存 4.退出 --------------------------- EOF while true do read -p "请选择功能(1~4):" num case $num in 1) echo "hostname: `cat /etc/hostname | awk ‘BEGIN{FS="."}{print $1}‘`" echo "system: `uname -r`" echo "------------------/dev/sda1--------------------------" echo "path:`df -h | awk ‘BEGIN{FS=" "}/^\/dev\/sda1/{print $1}‘`" echo "size:`df -h | awk ‘BEGIN{FS=" "}/^\/dev\/sda1/{print $2}‘`" echo "file_os:`df -T | awk ‘BEGIN{FS=" "}/^\/dev\/sda1/{print $2}‘`" echo "mount_on:`df -h | awk ‘BEGIN{FS=" "}/^\/dev\/sda1/{print $6}‘`" echo "------------------/dev/sda2--------------------------" echo "path:`df -h | awk ‘BEGIN{FS=" "}/^\/dev\/sda2/{print $1}‘`" echo "size:`df -h | awk ‘BEGIN{FS=" "}/^\/dev\/sda2/{print $2}‘`" echo "file_os:`df -T | awk ‘BEGIN{FS=" "}/^\/dev\/sda2/{print $2}‘`" echo "mount_on:`df -h | awk ‘BEGIN{FS=" "}/^\/dev\/sda2/{print $6}‘`" ;; 2) echo "1分钟平均负载:`uptime | awk ‘BEGIN{FS="[ |,]"}{print $14}‘`" echo "10分钟平均负载:`uptime | awk ‘BEGIN{FS="[ |,]"}{print $16}‘`" echo "15分钟平均负载:`uptime | awk ‘BEGIN{FS="[ |,]"}{print $18}‘`" ;; 3) echo "目前可用内存:`free -h | awk ‘BEGIN{FS=" "} /^M/ {print $4}‘`" echo "可用Swap分区:`free -h | awk ‘BEGIN{FS=" "} /^S/ {print $4}‘`" ;; 4) exit 0 ;; *) echo "请输入正确的菜单项!" esac done
5.shell解决就餐问题
shell 编程完成以下需求。
1 食堂:中国人(人民币) 2 食堂:外国人(美元) 汇率 6.798 菜单: 宫保鸡丁 (1)(荤): 8.6 鱼香肉丝 (2)(荤):2.5 豆芽炒青菜 (1)(素):5.5 椒盐蘑菇 (2)(素):1.9
倘若一哥们每天必须吃一个肉一个素;用脚本实现搭配的最低消费。
array=( "宫保鸡丁 (1)(荤):8.6" "鱼香肉丝 (2)(荤):2.5" "豆芽炒青菜 (1)(素):5.5" "椒盐蘑菇 (2)(素):1.9" ) #检查临时菜单是否存在,存在则删除 check(){ test -f caidan.txt if [ $? -eq 0 ] then rm -rf caidan.txt fi test -f file01.tmp if [ $? -eq 0 ] then rm -rf file01.tmp fi } #创建临时菜单文件 create(){ for var in ${array[@]} do echo $var >> caidan.txt done } #菜单文件处理及结果输出 operate(){ array01=(`cat caidan.txt |grep \(2\)`) b=`cat caidan.txt |grep \(1\)` a=`for j in ${array01[@]};do echo $j;done |awk -F: -v OFS=‘:‘ ‘{print $1,$2*6.798}‘` for i in $b do echo $i >> file01.tmp done for j in $a do echo $j >> file01.tmp done array02=(`cat file01.tmp |grep \(荤\)`) array03=(`cat file01.tmp |grep \(素\)`) c=`for k in ${array02[@]};do echo $k;done |sort -n -k2 |head -1` d=`for z in ${array03[@]};do echo $z;done |sort -n -k2 |head -1` echo $c echo $d } check create operate check
6.shell开发运维管理工具(2)
编写1个弹出式菜单的shell程序并实现其简单的菜单功能
******************************************************* * MENU * * 1.copy 2.rename * * 3.remove 4.find * * 5.exit * *******************************************************
用户按下数字1,则提示用户输入源和目的文件名后执行复制;输入数字2,则提示用户输入要更名的文件或目录后执行更名操作;输入数字3,则提示用户输入要删除的文件并执行删除操作;输入数字4,则提示用户输入要查找的文件并执行查找操作;输入数字5,则退出该菜单shell程序的执行。
#shell实现复制、重命名、删除、查找 cat << EOF ******************************************************* * MENU * * 1.copy 2.rename * * 3.remove 4.find * * 5.exit * ******************************************************* EOF output(){ if [ $1 -eq 0 ] then echo "success" else echo "fail" fi } while true do read -p "请选择功能(0-5):" num case $num in 1) read -p "请输入源和目的文件名(绝对路径):" s d cp -r $s $d output $? ;; 2) read -p "请输入要更名的文件或目录(绝对路径):" old new mv $old $new output $? ;; 3) read -p "请输入要删除的文件(绝对路径):" filename rm -rf $filename output $? ;; 4) read -p "请输入要查找的文件:" name find / -name $name ;; 5) exit ;; *) echo "请输入数字0-5!" esac done
7.自动删除用户账号
编写shell程序,实现自动删除50个用户账号的功能,账号名为stud1至stud50
#自动删除50个用户账号 j=0 for i in `seq 1 50` do userdel -r stud$i &>/dev/null if [ $? -eq 0 ] then j=$(($j+1)) else echo "用户账号stu$i不存在" fi done echo "$j个用户账号删除完毕,$(($i-$j))个用户账号不存在"
删除5个账号测试:
8.九九乘法表
#九九乘法表 for((i=1;i<=9;i++)) do for((j=1;j<=i;j++)) do # echo -ne "$i*$j=$(($i*$j))\t" echo -ne "$(($i*$j))\t" done echo "" done
9.文本处理面试题
(1)[腾讯面试题]:一个文本类型的文件,里面每行存放一个登陆者的IP(某些行是重复的),写一个shell脚本输出登陆次数最多的用户。
Ip_input.txt的内容假设如下:
219.217.49.14
175.43.4.87
87.48.98.1
59.73.38.25
219.217.50.14
59.92.48.32
219.217.49.14
59.72.38.142
59.73.38.25
219.217.49.14
#!/bin/bash echo "登陆次数最多的用户IP为:`sort Ip_input.txt|uniq -c|sort -nr|awk ‘{print $2}‘|head -n 1`"
(2)腾讯shell试题
假设qq.tel文件内容:
12334:13510014336
12345:12334555666
12334:12343453453
12099:13598989899
12334:12345454545
12099:12343454544
请分类如下:
[12334]
13510014336
12343453453
...........
[12099]
13598989899
12343454544
............sort qq.tel|awk -F: ‘{if(tmp!=$1){tmp=$1;print "["tmp"]";}print $2}‘
(3) 文件内容如下:
100
a 100
b -50
c -20
d -30
要求输出结果为:
100
a 100
200
b -50
150
c -20
130
d -30awk ‘NR==1{sum=$1;print $0}NR!=1{print $0;sum=sum-$2;print sum}‘ file
(4)文件内容如下:
123abc456
456def123
567abc789
789def567
要求输出:
456ABC123
123DEF456
789ABC567
567DEF789sed -r ‘s/([1-9]{3})([a-f]{3})([1-9]{3})/\3\2\1/;y/abcdef/ABCDEF/‘ file
(5)文件内容如下
1.1.1.1 11
1.1.1.1 22
1.1.1.1 33
1.1.1.1 44
2.2.2.2 11
2.2.2.2 22
2.2.2.2 33
2.2.2.2 44
要求使用awk将文件输出:
1.1.1.1 11 22 33 44
2.2.2.2 11 22 33 44awk ‘{sum[$1]=sum[$1]" "$2}END{for(var in sum)print var sum[var]}‘ file
10.判断一个指定的脚本是否有语法错误
写一个脚本,判断一个指定的脚本是否是语法错误。如果有错误,则提醒用户键入Q或者q:无视错误并退出;其它任何键可以通过vim打开这个指定的脚本。
#!/bin/bash read -p "please input check script:" file if [ -f $file ] then sh -n $file >/dev/null 2>&1 if [ $? -ne 0 ] then read -p "you input $file syntax error,[Type q/Q to exit or Type other to edit]" answer case $answer in Q|q) exit 0 ;; *) vim $file ;; esac fi else echo $file is not exist exit 1 fi
11.wget下载管理
创建一个函数,能接受两个参数:
1)第一个参数为URL,即可下载的文件;第二个参数为目录,即下载后保存的位置;
2)如果用户给的目录不存在,则提示用户是否创建;如果创建就继续执行,否则,函数返回一个51的错误值给调用脚本;
3)如果给的目录存在,则下载文件;下载命令执行结束后测试文件下载成功与否;如果成功,则返回0给调用脚本,否则,返回52给调用脚本;
#!/bin/bash #根据用户输入创建保存目录或退出执行 checkmk(){ if [ $2 == "y" ] then mkdir -p $1 tmp2=0 elif [ $2 == "n" ] then tmp2=51 else echo "[y/n]输入错误error" fi return $tmp2 } #检查下载保存目录是否存在,若存在则下载,否则询问是否创建保存目录 checkdir(){ if [ -d $1 ] then tmp=0 else tmp=51 read -p "是否要创建目录$1[y/n]?" answer checkmk $1 $answer temp=$? if [ $temp -ne 0 ] then echo "用户不同意创建目录,错误码:$temp" else tmp=0 echo "$1目录创建成功" fi fi return $tmp } #下载文件 download(){ checkdir $2 tmp1=$? if [ $tmp1 -eq 0 ] then wget -P $2 -rnd $1 >/dev/null 2>&1 if [ $? -eq 0 ] then tmp2=0 else tmp2=52 fi fi return $tmp2 } #主函数接受两个参数:URL和目录 main(){ download $1 $2 if [ $? -eq 0 ] then echo "wget is successful" else echo "wget is error,错误码:52" fi } main $1 $2
12.解压缩程序
编写一个shell程序,分别能够解压gz、bz2、xz和zip格式文件,其他文件给出提出信息“不认识文件类型”
建立测试文件:
# tar czvf a.tar.gz *.sh
# tar cjvf b.tar.bz2 *.sh
# tar cJvf c.tar.xz *.sh
# zip d.zip *.sh
#!/bin/bash check(){ if [ $1 -eq 0 ] then echo "$file decompressed successfully" else echo "$file decompressed failed" fi } read -p "请输入要解压文件的名称:" file if [ -f $file ] then case $file in *gz) tar xzvf $file >/dev/null check $? ;; *bz2) tar xjvf $file >/dev/null check $? ;; *xz) tar xJvf $file >/dev/null check $? ;; *zip) unzip -n $file >/dev/null check $? ;; *) echo "文件格式不正确,无法解压" esac else echo "$file文件不存在" fi