第十二章 Shell脚本编写及常见面试题(三)
本章目录: 12.21 FTP下载文件 #!/bin/bash if[$#-ne1];then echo"Usage:$0filename" fi dir=$(dirname$1) file=$(basename$1) ftp-n-v<<EOF#-n自动登录 open192.168.1.10 useradminadminpass binary#设置ftp传输模式为二进制,避免MD5值不同或.tar.gz压缩包格式错误 cd$dir get"$file" EOF 12.22 输入五个100数之内的字符,统计和、最小和最大 COUNT=1 SUM=0 MIN=0 MAX=100 while[$COUNT-le5];do read-p"请输入1-10个整数:"INT if[[!$INT=~^[0-9]+$]];then echo"输入必须是整数!" exit1 elif[[$INT-gt100]];then echo"输入必须是100以内!" exit1 fi SUM=$(($SUM+$INT)) [$MIN-lt$INT]&&MIN=$INT [$MAX-gt$INT]&&MAX=$INT letCOUNT++ done echo"SUM:$SUM" echo"MIN:$MIN" echo"MAX:$MAX"
12.23 将结果分别赋值给变量 方法1: foriin$(echo"456");do evala$i=$i done echo$a4$a5$a6 方法2:将位置参数192.168.18.1{1,2}拆分为到每个变量 num=0 foriin$(evalecho$*);do#eval将{1,2}分解为12 letnum+=1 evalnode${num}="$i" done echo$node1$node2$node3 #basha.sh192.168.18.1{1,2} 192.168.18.11192.168.18.12 方法3: arr=(456) INDEX1=$(echo${arr[0]}) INDEX2=$(echo${arr[1]}) INDEX3=$(echo${arr[2]}) 12.24 批量修改文件名 #toucharticle_{1..3}.html #ls article_1.htmlarticle_2.htmlarticle_3.html 现在想把article改为bbs: 方法1: forfilein$(ls*html);do mv$filebbs_${file#*_} #mv$file$(echo$file|sed-r's/.*(_.*)/bbs1/') #mv$file$(echo$file|echobbs_$(cut-d_-f2) done 方法2: forfilein$(find.-maxdepth1-name"*html");do mv$filebbs_${file#*_} done 方法3: #renamearticlebbs*.html 12.25 统计当前目录中以.html结尾的文件总大小 方法1: #find.-name"*.html"-maxdepth1-execdu-b{};|awk'{sum+=$1}END{printsum}' 方法2: forsizein$(ls-l*.html|awk'{print$5}');do sum=$(($sum+$size)) done echo$sum 递归统计: #find.-name"*.html"-execdu-k{};|awk'{sum+=$1}END{printsum}' 12.26 扫描主机端口状态
#!/bin/bash HOST=$1 PORT="2225808080" forPORTin$PORT;do ifecho&>/dev/null>/dev/tcp/$HOST/$PORT;then echo"$PORTopen" else echo"$PORTclose" fi done
12.27 Expect实现SSH免交互执行命令 需要先安装expect工具。 expect涉及用法说明: 命令描述 set可以设置超时,也可以设置变量 timeout超时等待时间,默认10s spawn执行一个命令 expect ""匹配输出的内容 exp_continue继续执行下面匹配 r回车 $argc统计位置参数数量 [lindex $argv 0]位置参数 puts打印字符串,类似于echo expect{...}输入多行记录 方法1:EOF标准输出作为expect标准输入 #!/bin/bash USER=root PASS=123.com IP=192.168.1.120 expect<<EOF settimeout30 spawnssh$USER@$IP expect{ "(yes/no)"{send"yesr";exp_continue} "password:"{send"$PASSr"} } expect"$USER@*"{send"$1r"} expect"$USER@*"{send"exitr"} expecteof EOF 方法2: #!/bin/bash USER=root PASS=123.com IP=192.168.1.120 expect-c" spawnssh$USER@$IP expect{ "(yes/no)"{send"yesr";exp_continue} "password:"{send"$PASSr";exp_continue} "$USER@*"{send"df-hrexitr";exp_continue} }" 方法3:将expect脚本独立出来 login.exp登录文件: #!/usr/bin/expect setip[lindex$argv0] setuser[lindex$argv1] setpasswd[lindex$argv2] setcmd[lindex$argv3] if{$argc!=4}{ puts"Usage:expectlogin.expipuserpasswd" exit1 } settimeout30 spawnssh$user@$ip expect{ "(yes/no)"{send"yesr";exp_continue} "password:"{send"$passwdr"} } expect"$user@*"{send"$cmdr"} expect"$user@*"{send"exitr"} expecteof 执行命令脚本: #!/bin/bash HOST_INFO=user_info foripin$(awk'{print$1}'$HOST_INFO) do user=$(awk-vI="$ip"'I==$1{print$2}'$HOST_INFO) pass=$(awk-vI="$ip"'I==$1{print$3}'$HOST_INFO) expectlogin.exp$ip$user$pass$1 done SSH连接信息文件: # cat user_info 192.168.1.120 root 123456 12.28 批量修改服务器用户密码 旧密码SSH主机信息old_info文件: # ip user passwd port #-------------------------------------- 192.168.18.217 root 123456 22 192.168.18.218 root 123456 22 修改密码脚本: #!/bin/bash OLD_INFO=old_info NEW_INFO=new_info forIPin$(awk'/^[^#]/{print$1}'$OLD_INFO);do USER=$(awk-vI=$IP'I==$1{print$2}'$OLD_INFO) PASS=$(awk-vI=$IP'I==$1{print$3}'$OLD_INFO) PORT=$(awk-vI=$IP'I==$1{print$4}'$OLD_INFO) NEW_PASS=$(mkpasswd-l8) echo"$IP$USER$NEW_PASS$PORT">>$NEW_INFO expect-c" spawnssh-p$PORT$USER@$IP settimeout2 expect{ "(yes/no)"{send"yesr";exp_continue} "password:"{send"$PASSr";exp_continue} "$USER@*"{send"echo'$NEW_PASS'|passwd--stdin$USERrexitr";exp_continue} }" done 生成新密码new_info文件: 192.168.18.217 root n8wX3mU% 22 192.168.18.218 root c87;ZnnL 22 12.29 打印乘法口诀 方法1: #awk'BEGIN{for(n=0;n++<9;){for(i=0;i++<n;)printfi"x"n"="i*n"";print""}}' 方法2: for((i=1;i<=9;i++));do for((j=1;j<=i;j++));do result=$(($i*$j)) echo-n"$j*$i=$result" done echo done
12.30 getopts工具完善脚本命令行参数 getopts是一个解析脚本选项参数的工具。 命令格式:getopts optstring name [arg] 初次使用你要注意这几点: 1)脚本位置参数会与optstring中的单个字母逐个匹配,如果匹配到就赋值给name,否则赋值name为问号; 2)optstring中单个字母是一个选项,如果字母后面加冒号,表示该选项后面带参数,参数值并会赋值给OPTARG变量; 3)optstring中第一个是冒号,表示屏蔽系统错误(test.sh: illegal option -- h); 4)允许把选项放一起,例如-ab 下面写一个打印文件指定行的简单例子,用于引导你思路,扩展你的脚本选项功能: #!/bin/bash whilegetopts:f:n:option;do case$optionin f) FILE=$OPTARG [!-f$FILE]&&echo"$FILEFilenotexist!"&&exit ;; n) sed-n"${OPTARG}p"$FILE ;; ?) echo"Usage:$0-f<file_path>-n<line_number>" echo"-f,--filespecifiedfile" echo"-n,--line-numberprintspecifiedline" exit1 ;; esac done
思路扩展:限定脚本参数,将参数保存变量,下面调用变量继续操作。 本章写的Shell脚本例子都比较实用,在面试题中也经常出现,希望大家多动手练习,不要复制粘贴就拿来跑,这样是学不会的!有问题请加群交流:323779636(Shell/Python运维开发群) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |