• 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 $username@192.168.42.$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))	"
            echo -ne "$(($i*$j))	"
        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 -30
    awk 'NR==1{sum=$1;print $0}NR!=1{print $0;sum=sum-$2;print sum}' file
    (4)文件内容如下:
    123abc456
    456def123
    567abc789
    789def567
    要求输出:
    456ABC123
    123DEF456
    789ABC567
    567DEF789
    sed -r 's/([1-9]{3})([a-f]{3})([1-9]{3})/321/;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 44
    awk '{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
    

    在这里插入图片描述

  • 相关阅读:
    一个涉及到浮点寄存器的CM
    树和二叉树一篇就搞定!
    串的两种模式匹配方式(BF/KMP算法)
    队列的知识讲解与基本实现(数据结构)
    如何用C++实现栈
    判断List集合为空还是null的正确打开方式
    双链表的基本实现与讲解(C++描述)
    Redis从认识安装到实现增删改查
    如何使用C++实现单链表
    线性表——顺序表的实现与讲解(C++描述)
  • 原文地址:https://www.cnblogs.com/zhaoya2019/p/13141787.html
Copyright © 2020-2023  润新知