zoukankan      html  css  js  c++  java
  • Linux 脚本运维总结之Shell script

    1. 本地变量和环境变量

    变量类型 定义形式 声明位置 显示命令 作用域
    本地变量 VARNAME=value 命令行或shell脚本 set (显示所有变量) 本用户,本进程
    环境变量 export VARNAME=value ~/.bash_profile (当前登陆用户有效)/etc/profile (所有登陆用户有效) env(仅显示环境变量) 所有用户所有进程

    2. 脚本调试

    • 法一
    #!/bin/bash -x
    
    • 法二
    set -x
    要调试的几行代码
    set +x
    

    3. 退出状态

    exit n    # n=0正常,n!=0出错,n~[0-255]
    
    脚本中没有exit命令则以最后一条命令的退出码为整个脚本的退出码
    
    $?    上一条命令的退出码
    

    4. 变量连接

    Linux把${}中的变量视作一个整体。${}会将其后的内容连接处理。

    BABY="cerana"    注意赋值的=号前后不要留白,否则变量将被当做shell命令执行,而后边的内容解释为参数。
    
    BABY_svn="hello"
    
    echo ${BABY}_svn    显示 cerana_svn
    echo ${BABY}:babala    显示cerana:babala
    echo ${BABY_svn}    显示 hello
    

    5. shell script中的常用命令

    :与true语句功能相同,产生测试结果为真的结果
    如:
    while :
    do
        ......
    done
    
    echo -n "Enter your name: "    -n不输出换行符
    read name    将控制台输入赋给变量name 
    或者
    read -p "Enter your name: " name
    
    expr 整数运算
    expr 1 + 1
    expr 1 - 1
    expr 3 * 4
    expr 3 / 4  为0,是整除
    echo 2^3 | bc 指数运算
    expr "abc" = "Abc" 返回0
    expr "abc" = "abc" 返回1
    echo "scale=2;1.2*7.8" | bc  scale控制小数位数
    echo "scale=2;13/2" | bc
    
    n=1
    let n+=3  支持+=, -=, *=, /=, %=
    

    6. 数值常数

    0 开头表示八进制数
    0x或者0X 开通表示十六进制数

    7. 命令替换

    ` ... ` 或者$( ... )
    

    8. test语句

    test expression
    [ expression ]  注意方括号内部前后要留白
    [[ expression ]] 注意方括号内部前后要留白(扩展形式)
    

    9. 文件测试

    测试语句 描述
    -e file 给定的文件存在
    -r file 给定的文件存在,且当前用户可读
    -w file 给定的文件存在,且当前用户可写
    -x file 给定的文件存在,且当前用户可执行
    -s file 给定的文件存在,且文件非空
    -f file 给定的文件存在,且为普通文件
    -d file 给定的文件存在,且是一个目录
    -L file 给定的文件存在,且是一个符号链接
    -c file 给定的文件存在,且是一个字符特殊文件
    -b file 给定的文件存在,且是一个块特殊文件
    -p file 给定的文件存在,且是一个命名管道文件
    BACKUPDIR=/data/backup
    [ -d ${BACKUPDIR} ] || mkdir -p ${BACKUPDIR}
    [ ! -d ${BACKUPDIR}/bin ] && rm -rf ${BACKUPDIR}/bin
    

    10. 字符串测试

    测试语句 描述
    -z str 给定的字符串长度为0,字符串要加双引号
    -n str 给定的字符串长度不为0,字符串要加双引号
    s1=s2 字符串相等
    s1!=s2 字符串不等
    s1<s2 字符串比较
    s1>s2 字符串比较

    11. 数值比较

    测试语句 描述
    -eq 等于
    -ne 不等于
    -gt 大于
    -lt 小于
    -ge 大于等于
    -le 小于等于

    12. 逻辑运算

    测试语句 描述
    ( ) 组合
    ! exp
    -a 或 &&
    -o 或 ││

    13. 函数

    function fname(){
        cmd;
        [return 数值;]  如果不加此句则将最后一条命令的执行结果作为退出码
    }
    

    例子

    #!/bin/bash 
    
    function traverse(){
        dir=$(echo $1 | sed "s|/$||")
    
        for file in `ls $dir`
        do
            if [ -d $dir"/"$file ]
            then
                traverse $dir"/"$file
            else
                echo $dir"/"$file
            fi
        done
    }
    
    traverse $1
    

    14. 字符串截取

    命令 说明
    ${var##*str} 从左向右截取最后一个str后的字符串
    ${var#*str} 从左向右截取第一个str后的字符串
    ${var%%str*} 从右向左截取最后一个str后的字符串
    ${var%str*} 从右向左截取第一个str后的字符串
    ${var:n1:n2} 截取变量var从n1开始的n2个字符(n1从0开始)

    15. 控制结构

    • if分支
    if condition1
    then
        cmd1
    else
        cmd2
    fi
    
    或者
    if condition1
    then
        cmd1
    elif condition2
        cmd2
    else
        cmd3
    fi
    
    • case分支
    case value in
    mode1)
        cmd1
        ;;
    mode2|mode3)
        cmd2
        ;;
    mode4)
        cmd3
        ;;
    *)
        cmd4
        ;;;
    esac
    
    • 循环
    for var in list
    do
        cmds
    done
    
    for (( i=1;i<=20;i=i+1 )); do
        cmds
    done
    
    list可以为:
    列表,字符串,文件名,{100..200}
    
    while conditions
    do
        cmd
    done
    

    循环常用形式:

    for LINE in `cat file`
    或者
    cat $FILE | while read LINE
    

    16. sed基本用法

    sed [-nefr] [n1, n2] 'actions'
    

    sed常见参数

    例子:

    删除file的2~5行后再显示
    cat -n file | sed '2,5d'
    
    在文件file的第二行的下一行添加“Hello, world”字符串
    cat -n file | sed '2a Hello, world'
    
    注意:行末使用  转义回车换行符达到续行的效果。
    
    将2~5行的内容替换为baby girl
    cat -n file | sed '2,5c baby girl'
    
    只显示5~7行的内容
    cat -n file | sed -n '5,7p'
    
    实现字符串函数 trim() 的效果
    sed 's/^s*//' totrim.txt |sed 's/s*$//'>trimed.txt
    sed 's/^s*//;s/s*$//' totrim.txt>trimed.txt
    sed -e 's/^s*//' -e 's/s*$//' totrim.txt>trimed.txt
    
    设置去除,不要注释行
    cat /etc/man.config | grep 'MAN' | sed 's/#.*$//g' | sed '/^$/d'
    
    下加一行(&指代pattern)
    sed 's/pattern/&
    /g' file
    上加一行
    sed 's/pattern/
    &/g' file
    
    变量替换
    sed -e "s/$var1/$var2/g" file
    
    在第一行前插入文本---BEGIN---,在最后一行插入文本---END---。
    cat test4.txt | sed '1 i---BEGIN---' | sed '$ a---END---'
    
    在正则匹配行前插入string
    sed -i '/pattern/ i "string"' file
    在正则匹配行后插入string
    sed -i '/pattern/ a "string"' file
    
    将家目录~下所有文件中的abc都改为cba(g指一行中的每一列都要处理)
    sed -i 's/abc/cba/g' `grep abc -rl ~`
    其中:-r表示递归,但不包括符号连接,-l表示只列出匹配的文件名(绝对路径)。
    
    使用其他分隔符文本替换
    sed -i 's@http://[^.]*.1234.com@/home/html/www.2321.com@g' file
    
    行首添加注释#
    sed -i '1,20s/^/#/' file  只处理第一个匹配
    取消行首的#
    sed -i '1,20s/^#//' file  只处理第一个匹配
    
    提取日志记录
    sed -n '/2018-11-08 10:15:00/, /2018-11-11 10:15:00/p' logfile
    

    17. awk基本用法

    awk [-F field-seperator] 'pattern {action}' file
    BEGIN 初始化
    数据处理
    END 收尾处理
    注意:需使用单引号,以防被shell解释。
    pattern和{action}可以省略其中之一,但不能同时省略。
    action 中的语句以 ; 分隔。
    
    awk -F[:" "] ...    -F[:" "]表示以:和空格作为分隔符
    默认分隔符是空格
    
    内置变量
    FS  输入字段分隔符
    RS  输入记录分隔符
    OFS 输出字段分隔符
    ORS 输出记录分隔符
    NF  输入字段个数
    NR  输入当前记录编号
    $0  整条记录
    $n  第n条记录,n=1,2,3,...
    

    pattern{action}模式

    /^$/ {print "blank line"}
    $5~/MA/ {print $1" "$3}
    

    例子:

    抓取时间范围是Jun 30 10:30:00到Jun 30 11:00:00的日志记录
    cat /var/log/secure | grep "Jun 29" | awk '$3>="22:00:00" && $3<="22:30:00"'
    类似地有
    cat log1 | awk -F'	' '$1$2>="2013/08/16    01:16:11.111" && $1$2<="2013/08/16    01:25:22.222"'
    
    转换时间格式
    date -d "Jun 23 12:22:21" "+%F %T" 转换时间格式
    2018-06-23 12:22:21 回显
    echo "Jun 23 12:22:21" | awk '{NF=3;cmd="date -d ""$0"" "+%F %T"";cmd|getline dt;print dt;close(cmd)}'
    
    统计
    cat file | awk -F: 'BEGIN{count=0} $2>0{count+=$9} END{print count}'
    
    1. 常用运维脚本
    • ftp备份
    ftp -i -n -v << !
    open ${HOST}
    user ${USERNAME} ${PASSWORD}
    bin
    cd ${OLDDATE}
    mdelete *
    cd ..
    rmdir ${OLDDATE}
    mkdir ${DATE}
    cd ${DATE}
    mput *
    bye
    !
    
    • 批量添加/删除用户
      用户信息文件users.txt
    cerana1:13888298736
    cerana2:13888298737
    cerana3:13888298738
    cerana4:13888298739
    cerana5:13888298740
    

    批量添加用户的脚本

    #!/bin/bash
    #把本shell脚本和账号文件放在同一个目录下
    
    for line in `cat users.txt` ; do 
        username=$(echo $line | awk -F: '{print $1}')
        password=$(echo $line | awk -F: '{print $2}')
        useradd $username
        echo "User $username was added successfully" 
    
        #passwd --stdin表示不交互,直接输入密码
        echo $password | passwd --stdin $username
        #强制用户第一次登陆就必须更改密码
        chage -d 0 $username
        #定义密码有效期30天
        chage -M 30 $username
    done
    echo "Finish!"
    

    批量删除用户的脚本

    #!/bin/bash
    
    for line in `cat users.txt` ; do 
        username=$(echo $line | awk -F: '{print $1}')
        #同时删除用户home目录,邮箱等资源
        userdel -r $username
        echo "User $username was deleted successfully" 
    done
    echo "Finish!"
    
    • 通过ssh批量执行命令
    #!/bin/bash
    
    if [ $# -lt 1 ] ;then
        echo "Please input arguments for command"
        exit 1;
    fi
    echo ------------run $1 on local-------------
    $@
    echo
    for (( i=100;i<=500;i=i+100 )); do  # 或者for i in $(seq 100 100 500); do
        echo -------------run $1 on Node$i ---------------
        ssh Node$i $@
        echo
    done
    
  • 相关阅读:
    【Windows】netsh动态配置端口转发
    Python 脚本注册为Windows Service
    【Windows】Python脚本随机启动
    【MySQL】CSV 文件导入MySQL
    【Python】改变对象的字符串显示
    【Python】偏函数
    【Python】装饰器理解
    【Python】什么是闭包
    【Python】高阶函数介绍
    【Python】__all__ 暴露接口
  • 原文地址:https://www.cnblogs.com/cerana/p/11108362.html
Copyright © 2011-2022 走看看