上一篇:30个Linux Shell脚本经典案例(中)

本章目录

21、从FTP服务器下载文件

22、连续输入5个100以内的数字,统计和、最小和最大

23、将结果分别赋值给变量

24、批量修改文件名

25、统计当前目录中以.html结尾的文件总大

26、扫描主机端口状态

27、Expect实现SSH免交互执行命令

28、批量修改服务器用户密码

29、打印乘法口诀

30、getopts工具完善脚本命令行参数


21、从FTP服务器下载文件

#!/bin/bashif [ $# -ne 1 ]; then    echo "Usage: $0 filename"fidir=$(dirname $1)file=$(basename $1)ftp -n -v << EOF   # -n 自动登录open 192.168.1.10  # ftp服务器user admin passwordbinary   # 设置ftp传输模式为二进制,避免MD5值不同或.tar.gz压缩包格式错误cd $dirget "$file"EOF

22、连续输入5个100以内的数字,统计和、最小和最大

#!/bin/bashCOUNT=1SUM=0MIN=0MAX=100while [ $COUNT -le 5 ]; do    read -p "请输入1-10个整数:" INT    if [[ ! $INT =~ ^[0-9]+$ ]]; then        echo "输入必须是整数!"        exit 1    elif [[ $INT -gt 100 ]]; then        echo "输入必须是100以内!"        exit 1    fi    SUM=$(($SUM+$INT))    [ $MIN -lt $INT ] && MIN=$INT    [ $MAX -gt $INT ] && MAX=$INT    let COUNT++doneecho "SUM: $SUM"echo "MIN: $MIN"echo "MAX: $MAX"

23、将结果分别赋值给变量

应用场景:希望将执行结果或者位置参数赋值给变量,以便后续使用。

方法1:

for i in $(echo "4 5 6"); do   eval a$i=$idoneecho $a4 $a5 $a6

方法2:将位置参数192.168.1.1{1,2}拆分为到每个变量

num=0
for i in $(eval echo $*);do #eval将{1,2}分解为1 2
let num+=1
eval node${num}="$i"
done
echo $node1 $node2 $node3

bash a.sh 192.168.1.1{1,2}

192.168.1.11 192.168.1.12

方法3:arr=(4 5 6)INDEX1=$(echo ${arr[0]})INDEX2=$(echo ${arr[1]})INDEX3=$(echo ${arr[2]})

24、批量修改文件名

示例:

# touch article_{1..3}.html# lsarticle_1.html  article_2.html  article_3.html

目的:把article改为bbs

方法1:

for file in $(ls *html); do    mv $file bbs_${file#*_}    # mv $file $(echo $file |sed -r 's/.*(_.*)/bbs\1/')    # mv $file $(echo $file |echo bbs_$(cut -d_ -f2)done

方法2:

for file in $(find . -maxdepth 1 -name "*html"); do     mv $file bbs_${file#*_}done

方法3:

# rename article bbs *.html

25、统计当前目录中以.html结尾的文件总大

方法1:

# find . -name "*.html" -exec du -k {} \; |awk '{sum+=$1}END{print sum}'

方法2:

for size in $(ls -l *.html |awk '{print $5}'); do    sum=$(($sum+$size))doneecho $sum

26、扫描主机端口状态

#!/bin/bashHOST=$1PORT="22 25 80 8080"for PORT in $PORT; do    if echo &>/dev/null > /dev/tcp/$HOST/$PORT; then        echo "$PORT open"    else        echo "$PORT close"    fidone

27、Expect实现SSH免交互执行命令

Expect是一个自动交互式应用程序的工具,如telnet,ftp,passwd等。

需先安装expect软件包。

方法1:EOF标准输出作为expect标准输入

#!/bin/bashUSER=rootPASS=123.comIP=192.168.1.120expect << EOFset timeout 30spawn ssh $USER@$IP   expect {    "(yes/no)" {send "yes\r"; exp_continue}    "password:" {send "$PASS\r"}}expect "$USER@*"  {send "$1\r"}expect "$USER@*"  {send "exit\r"}expect eofEOF

方法2:

#!/bin/bashUSER=rootPASS=123.comIP=192.168.1.120expect -c "    spawn ssh $USER@$IP    expect {        \"(yes/no)\" {send \"yes\r\"; exp_continue}        \"password:\" {send \"$PASS\r\"; exp_continue}        \"$USER@*\" {send \"df -h\r exit\r\"; exp_continue}    }"

方法3:将expect脚本独立出来

登录脚本:

# cat login.exp#!/usr/bin/expectset ip [lindex $argv 0]set user [lindex $argv 1]set passwd [lindex $argv 2]set cmd [lindex $argv 3]if { $argc != 4 } {puts "Usage: expect login.exp ip user passwd"exit 1}set timeout 30spawn ssh $user@$ipexpect {    "(yes/no)" {send "yes\r"; exp_continue}    "password:" {send "$passwd\r"}}expect "$user@*"  {send "$cmd\r"}expect "$user@*"  {send "exit\r"}expect eof

执行命令脚本:写个循环可以批量操作多台服务器

#!/bin/bashHOST_INFO=user_info.txtfor ip in $(awk '{print $1}' $HOST_INFO)do    user=$(awk -v I="$ip" 'I==$1{print $2}' $HOST_INFO)    pass=$(awk -v I="$ip" 'I==$1{print $3}' $HOST_INFO)    expect login.exp $ip $user $pass $1done

Linux主机SSH连接信息:

# cat user_info.txt192.168.1.120 root 123456

28、批量修改服务器用户密码

Linux主机SSH连接信息:旧密码

# cat old_pass.txt 192.168.18.217  root    123456     22192.168.18.218  root    123456     22

内容格式:IP User Password Port

SSH远程修改密码脚本:新密码随机生成

#!/bin/bashOLD_INFO=old_pass.txtNEW_INFO=new_pass.txtfor IP in $(awk '/^[^#]/{print $1}' $OLD_INFO); do    USER=$(awk -v I=$IP 'I==$1{print $2}' $OLD_INFO)    PASS=$(awk -v I=$IP 'I==$1{print $3}' $OLD_INFO)    PORT=$(awk -v I=$IP 'I==$1{print $4}' $OLD_INFO)    NEW_PASS=$(mkpasswd -l 8)  # 随机密码    echo "$IP   $USER   $NEW_PASS   $PORT" >> $NEW_INFO    expect -c "    spawn ssh -p$PORT $USER@$IP    set timeout 2    expect {        \"(yes/no)\" {send \"yes\r\";exp_continue}        \"password:\" {send \"$PASS\r\";exp_continue}        \"$USER@*\" {send \"echo \'$NEW_PASS\' |passwd --stdin $USER\r exit\r\";exp_continue}    }"done

生成新密码文件:

# cat new_pass.txt 192.168.18.217  root    n8wX3mU%      22192.168.18.218  root    c87;ZnnL      22

29、打印乘法口诀

方法1:

# awk 'BEGIN{for(n=0;n++<9;){for(i=0;i++<n;)printf i"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   echodone

30、getopts工具完善脚本命令行参数

getopts是一个解析脚本选项参数的工具。

命令格式:getopts optstring name [arg]

初次使用你要注意这几点:

  • 脚本位置参数会与optstring中的单个字母逐个匹配,如果匹配到就赋值给name,否则赋值name为问号;

  • optstring中单个字母是一个选项,如果字母后面加冒号,表示该选项后面带参数,参数值并会赋值给OPTARG变量;

  • optstring中第一个是冒号,表示屏蔽系统错误(test.sh: illegal option -- h);

  • 允许把选项放一起,例如-ab

下面写一个打印文件指定行的简单例子,引导你思路:

#!/bin/bashwhile getopts :f:n: option; do    case $option in        f)            FILE=$OPTARG      [ ! -f $FILE ] && echo "$FILE File not exist!" && exit            ;;        n)            sed -n "${OPTARG}p" $FILE            ;;        ?)            echo "Usage: $0 -f <file_path> -n <line_number>"            echo "-f, --file           specified file"            echo "-n, --line-number    print specified line"            exit 1        ;;    esacdone

根据工作经验总结的30个Shell脚本案例至此完结,都还是比较实用的,面试笔试题也经常会出。希望朋友们多动手练一练,让你的Shell功底上升一个段位!

©著作权归作者所有:来自51CTO博客作者mob604756e5abbc的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Composer常用指令、安装组件、自动加载器使用方式与更新方法
  2. 最简单的JVM内存结构图
  3. 华为认证HCIP考试费报名费复习方法HCIE考试费报名费复习方法
  4. 查看域用户最后登录时间的方法
  5. pytorch转为onnx格式,和加载模型的params和GFLOPs方法
  6. Python实现双因素方法分析(Two-Way)
  7. select使用方法
  8. Nginx编译报错解决方法
  9. shell脚本中数组常用操作

随机推荐

  1. Apache Commons Configuration读取xml配
  2. Dom4j修改xml文档引入
  3. android sax创建xml文件
  4. java操作properties配置文件
  5. 根据Schema写出XML文档四部曲
  6. android sax解析 xml方式
  7. android XPath 解析xml
  8. xml解析之使用dom4j的api对xml文件进行CR
  9. android sax解析xml文件(二)
  10. 小心XmlPullParser.netText()方法