zoukankan      html  css  js  c++  java
  • 很有用的shell脚本

    基础知识

    expect基础知识

    • exp_continue是匹配一行后,从当前expect块第一行开始匹配
    • expect块的每一行匹配后,直接退出当前expect块,往下一个expect块开始匹配
    • expect块需要send的信息中包含双引号 ”“ ,需要进行 转义

    shell基础知识

    脚本其实就是短小的、用来让计算机自动化完成一系列工作的程序,这类程序可以用文本编辑器修改,不需要编译,通常是解释运行的。

    变量

    用语句给变量赋值

    for file in `ls /etc`
    或
    for file in $(ls /etc)
    或
    ip=`awk '{ print $1 }' iplist`  # 变量能重新赋值,使用变量可以用$ip、${ip}
    或
    ip=$(awk '{ print $1 }' iplist)

    函数

    • 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
    • 在函数体内部,当n>=10时,需要使用${n}来获取参数。
    • 函数返回值在调用该函数后通过 $? 来获得。

    处理参数列表

    参数处理说明
    $# 传递到脚本的参数个数
    $* 以一个单字符串显示所有向脚本传递的参数
    $$ 脚本运行的当前进程ID号
    $! 后台运行的最后一个进程的ID号
    $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
    $- 显示Shell使用的当前选项,与set命令功能相同。
    $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

    $@与$*加引号时区别:$@在引号中返回每个参数

    #!/usr/bin/bash
    source ./color.sh
    
    # "$*"
    echo -e "${RED}"$ *":"
    for i in "$*";do
    echo -e "${RED}$i${CLOSE_ALL}"
    done
    
    echo -e "
    "
    
    # "$@"
    echo -e "${BLUE}"$ @":"
    for i in "$@";do
    echo -e "${BLUE}$i${CLOSE_ALL}"
    done
    test.sh

    结果截图

    输入/输出重定向

     输入/输出重定向列表

    命令说明
    command > file 将输出重定向到 file。
    command < file 将输入重定向到 file。
    command >> file 将输出以追加的方式重定向到 file。
    n > file 将文件描述符为 n 的文件重定向到 file。
    n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
    n >& m 将输出文件 m 和 n 合并。
    n <& m 将输入文件 m 和 n 合并。
    << tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

    文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

    实例

    $ command1 < infile > outfile

    同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。

    $ command > file 2>&1
    $ find /etc -name "*.txt"  > list 2>&1

    stdout 和 stderr 合并后重定向到 file。先将要输出到stdout的内容重定向到文件,此时文件list就是这个程序的stdout,再将stderr重定向到stdout,也就是文件list。此时屏幕不显示信息,在list中显示,通过cat list查看。

    $ command  2>&1 > file
    $ find /etc -name "*.txt"  2>&1 >list

    stderr重定向到stdout,stdout重定向到file。先将要输出到stderr的内容重定向到stdout,此时会产生一个stdout的拷贝,作为程序的stderr,而程序原本要输出到stdout的内容,依然是对接在stdout原身上的,

    因此第二步重定向stdout,对stdout的拷贝不产生任何影响。此时屏幕会输出错误信息,标准输出在list中显示,通过cat list查看。

    $ command > /dev/null 2>&1

    屏蔽 stdout 和 stderr,不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null。/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。

    文件包含

    .  filename 
    
    或
    
    source filename

    包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。如实例中batch.sh通过source包含color.sh脚本。

    实例1、批量登录远程Linux服务器

    包括4个文件:batch.sh(批量管理expect登录脚本)color.sh(颜色脚本)、sshLogin.exp(expect登录脚本)、iplist(用于登录的IP、用户名和用户密码)

    batch.sh(批量管理expect登录脚本)

    #!/usr/bin/bash
    
    source ./color.sh
    
    callSSH() {
        # $$:pid $1:filename $2:username $3:ip $4:password
        echo -e "$GREEN Param init(pid: $$): $1 $2 $3 $4 $CLOSE_ALL"
        expect $1 $2 $3 $4
        return $?
    }
    
    sshManage() {
        i=1
        for ip in `awk 'NR>2 {print $1}' iplist`
        do
            user=$(awk -v IP=$ip '{if(IP==$1) print $2}' iplist)
            password=`awk -v IP=$ip '{if(IP==$1) print $3}' iplist`
    
            if [ $i -le 9 ]
            then
                i="0$i"
            else
                i="$i"
            fi
    
            echo -e "$BLUE<<--------------    Login $ip($i) begin   -------------->>$CLOSE_ALL"
            callSSH sshLogin.exp $user $ip $password
            echo -e "${BLUE}return_value = $? $CLOSE_ALL"
            echo -e "$BLUE<<--------------    Login $ip($i) end-------------->>$CLOSE_ALL"
            let "i++"
        done
    }
    
    echo -e "$RED<<<<<<<<<<<<<<<<<<<<<< sshManage begin >>>>>>>>>>>>>>>>>>>>>>$CLOSE_ALL"
    sshManage
    echo -e "$RED<<<<<<<<<<<<<<<<<<<<<<  sshManage end  >>>>>>>>>>>>>>>>>>>>>>$CLOSE_ALL"
    batch.sh

    color.sh(颜色脚本)

    #!/usr/bin/bash
    
    # Example:
    #       echo -e "33[字背景颜色;文字颜色m          字符串          33[0m"
    #       echo -e "33[41;36m                   something here       33[0m"
    #       echo -e "$RED                   something here       $CLOSE_ALL"
    
    # font color: 30-37
    BLACK="33[30m"                            # 黑色
    RED="33[31m"                              # 红色
    GREEN="33[32m"                            # 绿色
    YELLOW="33[33m"                           # 黄色
    BLUE="33[34m"                             # 蓝色
    PURPLE="33[35m"                           # 紫色
    SKY_BLUE="33[36m"                         # 天蓝色
    WHITE="33[37m"                            # 白色
    
    # blackground color: 40-47
    BLACK_WHITE="33[40;37m"                   # 黑底白字
    RED_WHITE="33[41;37m"                     # 红底白字
    GREEN_WHITE="33[42;37m"                   # 绿底白字
    YELLOW_WHITE="33[43;37m"                  # 黄底白字
    BLUE_WHITE="33[44;37m"                    # 蓝底白字
    PURPLE_WHITE="33[45;37m"                  # 紫底白字
    SKY_BLUE_WHITE="33[46;37m"                # 天蓝底白字
    WHITE_BLACK="33[47;30m"                   # 白底黑字
    
    # Control options
    CLOSE_ALL="33[0m"                          # 关闭所有属性
    HIGH_BRIGHTNESS="33[1m"                   # 设置高亮度
    UNDERLINE="33[4m"                         # 下划线
    FLICKER="33[5m"                           # 闪烁
    REVERSE_DISPLAY="33[7m"                   # 反显
    SET_FOREGROUND="33[30m — 33[37m"          # 设置前景色
    SET_BACKGROUND="33[40m — 33[47m"          # 设置背景色
    SET_CURSOR_POS="33[y;xH"                   # 设置光标位置
    N_CURSOR_UP="33[nA"                       # 光标上移n行
    N_CURSOR_DOWN="33[nB"                     # 光标下移n行
    N_CURSOR_RIGHT="33[nC"                    # 光标右移n行
    N_CURSOR_LEFT="33[nD"                     # 光标左移n行
    CURSOR_POS_SAVE="33[s"                    # 保存光标位置
    CURSOR_POS_RECOVER="33[u"                 # 恢复光标位置
    CURSOR_HIDE="33[?25l"                     # 隐藏光标
    CURSOR_DISPLAY="33[?25h"                  # 显示光标
    CLEAR_SCREEN="33[2J"                      # 清屏
    CLEAR_CONTENT="33[K"                      # 清除从光标到行尾的内容
    color.sh

    sshLogin.exp(expect登录脚本)

    #!/usr/bin/expect
    
    if { $argc != 3 } {
        send -- "Usage: expect sshLogin.exp username ip password
    "
        exit 1
    }
    
    #Param
    set userName [lindex $argv 0]
    set IP [lindex $argv 1]
    set password [lindex $argv 2]
    set timeout 30
    
    spawn ssh -P22 $userName@$IP
    expect {
        eof { exit 0 }
        timeout { exit 1 }
        "*password*" { send -- "$password
    " }
        "*(yes/no)?*" { send -- "yes
    ";exp_continue }
    }
    
    expect {
        eof { exit 0 }
        timeout { exit 1 }
        "*#*" { send -- "find /etc -names "*.txt"  >list 2>&1
    " }
    }
    
    expect {
        eof { exit 0 }
        timeout { exit 1 }
        "*#*" { send -- "cat list
    " }
    }
    
    set timeout 5
    expect {
        eof { exit 0 }
        timeout { exit 1 }
        "*#*" { send -- "
    " }
    }
    
    expect {
        eof { exit 0 }
        timeout { exit 1 }
        "*#*" { send -- "exit
    " }
    }
    expect eof
    exit
    sshLogin.sh

    iplist(用于登录的IP、用户名和用户密码)

    #ip username password
    
    10.10.3.128 root ******
    10.10.1.21  root ******
    iplist

    结果截图

     实例2、批量激活脚本

    #!/bin/bash
    chmod 777 spv*.bin
    ./spv*.bin
    echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
    eth=`ifconfig |awk '{print $1}'  | awk 'NR==1{print}' | awk -F':' '{print $1}'`
    ip=`ifconfig  $eth | grep netmask |awk  '{print $2}'| awk -F '.' '{print $4}'`
    mv  /tmp/spv_License/spv_License/License$ip.txt /home/spv/config/spvlicense
    chown apache.apache /home/spv/config/spvlicense
    
    mysql -uuser -ppassword dbname -e "insert into user_role (userID,roleID) values (100,1);"
    
    #echo "first code is:"
    #cat /tmp/spv_License/spv_License/
    code=`cat /tmp/spv_License/spv_License/$ip\_license.txt`
    #echo "first code is:$code"
    echo -e "33[35m  first code is:$code 33[0m"
    
    #echo "please reboot this hac now"
    if [ $? == 0 ];
      then
       echo -e "33[35m  Import license success,please reboot this hac now. 33[0m"
     else
       echo -e "33[31m Import license failure,please Import license by yourself ! 33[0m"
    fi
    /tmp/spv_License/spv_License目录下的文件,包含所有的激活文件。

    eth为ifconfig下的第一列中的第一行以逗号分隔的第一个字段。也就是eth0。

    ip为ifconfig eth0下的查找关键字netmask所在行的第二个字段下以逗号分隔的第四个字段,也就是126。

    连接MySQL数据库,执行SQL:mysql -uuser -ppassword -e " sql "

    chown将spvlicense文件的拥有者改为apache.apache

    
    
    作者:yusq77

    -------------------------------------------

    Wish you all the best and good health in 2021.

  • 相关阅读:
    Spring Boot2(九):整合Jpa的基本使用
    Spring Boot2(八):性感banner,在线发牌
    Spring Boot2(七):拦截器和过滤器
    我为什么要写作
    代码整洁之道
    redis-缓存穿透和缓存击穿
    云计算的三种服务模式
    java-泛型
    java-注解
    java-反射
  • 原文地址:https://www.cnblogs.com/yusq77/p/10913427.html
Copyright © 2011-2022 走看看