zoukankan      html  css  js  c++  java
  • shell脚本


    shell脚本基础

    变量

    变量名称注意事项

    • 只能包含字母、数字、下划线,并且不能以数字开头
    • 不应该跟系统中已有的环境变量重名,尽量不要全部使用大写,尽量不要用“_”下划线开头
    • 最好做到见名知义
    • 不能使用程序中的保留字,例如iffor

    变量类型

    • 字符型
    • 数值型
    • 整型
    • 浮点型
    • 布尔型

    bash变量类型

    环境变量

    export VAR_NAME=VALUE   //作用域为当前shell进程及其子进程
    

    本地变量(局部变量)

    VAR_NAME=VALUE  //本地变量,作用域为当前shell进程
    local VAR_NAME=VALUE  //局部变量,作用域为当前代码段,常用于函数
    

    位置变量

    $1$2$3  //用来引用脚本的参数
    shift [num]  //位置变量使用完以后退出,后面的参数向前推进
    

    特殊变量

    • bash内置的,用来保存某些特殊数据的变量,也称系统变量
    • 常用:
      • $? 是显示上条命令的退出状态,0表示没有错误,其他表示有错误
      • $# 是传给脚本的参数个数
      • $0 是脚本本身的名字
      • $! 是shell最后运行的后台Process的PID
      • $@ 是传给脚本的所有参数的列表
      • $* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
      • $$ 是脚本运行的当前进程ID号

    bash内建环境变量

    • PATH 执行命令的定义变量
    • SHELL 当前使用的shell
    • UID 当前用户的UID
    • HISTSIZE 命令历史长度
    • HOME 当前用户家目录
    • PWD 当前工作目录
    • HISTFILE 历史命令记录的文件
    • PS1 定义命令提示符前的用户名主机名等

    只读变量(常量)

    readonly VAR_NAME=VALUE  //不能修改值,只能等shell进程终止时随之消亡
    

    脚本基础

    程序返回值

    • 程序执行以后有两类返回值:
      • 程序执行的结果
      • 程序状态返回代码(0-255)
        • 0:正确执行
        • 1-255:错误执行,1、2、127系统预留,有特殊意义

    脚本测试

    bash -n scriptname  //检查脚本是否有语法错误
    bash -x scriptname  //单步执行,检查脚本错在哪里
    

    写脚本注意事项

    • 禁止将未成功执行过的代码直接写进脚本
    • 脚本中的命令一定要用绝对路径

    shell算数运算

    A=3  //定义A变量值为3
    B=6  //定义B变量值为6
    
    let C=$A+$B  //let 算术运算表达式
    C=$[$A+$B]  //$[算术运算表达式]
    C=$(($A+$B))  //$((算术运算表达式))
    
    C=$A+$B  //算数加法
    C=$[$A-$B]  //算数减法
    C==$[$A*$B]  //算数乘法
    C=$(printf "%.2f" `echo "scale=2;$1/$2"|bc`)  //算数除法,保留各位的0
    

    命令间的逻辑关系

    • 逻辑与:&&
      • 第一个条件为假时,第二个条件不用再判断,最终结果已经有
      • 第一个条件为真时,第二个条件必须得判断
    • 逻辑或:||
      • 前一个命令的结果为真时,第二个命令就不执行
      • 前一个命令的结果为假时,第二个命令必须执行

    shell脚本进阶

    bash条件判断

    条件测试的表达式

    [ expression ]   //建议使用
    [[ expression ]]  //可以使用
    test expression  //不建议使用
    

    整数测试

    • -eq 测试两个整数是否相等
    • -ne 测试两个整数是否不等
    • -gt 测试一个数是否大于另一个数
    • -lt 测试一个数是否小于另一个数
    • -ge 大于或等于
    • -le 小于或等于

    字符测试

    ==   //等值比较,检查==两边的内容是否一致,==两边都要有空格
    !=   //检查两边内容是否不一致,不一致为真,一致为假
    =~   //左侧字符串是否能够被右侧的PATTERN所匹配到。此表达式应用于双中括号[[]]中
    -z "string"   //测试指定字符串是否为空,空则为真,不空则为假
    -n "string"   //测试指定字符串是否不空,不空则为真,空则为假
    

    文件测试

    • 存在性测试:
      • -e 测试文件是否存在
    • 存在性及类别测试
    • 常用:
      • -f 测试文件是否为普通文件
      • -d 测试指定路径是否为目录
    • 不常用
      • -b 测试文件是否为块设备文件
      • -c 测试文件是否为字符设备文件
      • -h 测试文件是否为符号链接文件
      • -L 测试文件是否为符号链接文件
      • -p 测试文件是否为命名管道文件
      • -S 测试文件是否为套接字文件
    • 文件权限测试:
      • -r 测试当前用户对指定文件是否有读权限
      • -w 测试当前用户对指定文件是否有写权限
      • -x 测试当前用户对指定文件是否有执行权限
    • 文件特殊权限测试:
      • -g 测试文件是否有sgid权限
      • -u 测试文件是否有suid权限
      • -k 测试文件是否有sticky权限
    • 文件大小测试:
      • -s 测试文件是否非空
    • 文件是否打开测试:
      • -t fd fd表示的文件描述符是否已经打开且与某终端相关
    • 双目测试:
      • file1 -ef file2 测试file1与file2是否指向同一个设备上的相同inode,说白点就是两者是不是同一个文件
      • file1 -nt file2 测试file1是否比file2新
      • file1 -ot file2 测试file1是否比file2旧
    • 无分类:
      • -N 测试文件自从上一次被读取之后是否被修改过
      • -O 测试文件是否存在并且被当前用户拥有
      • -G 测试文件是否存在并且默认组是否为当前用户组

    组合测试条件

    • -a 与关系,作用与&&相同
    • -o 或关系,作用与||相同
    • ! 非关系
    传入参数的个数大于1个,小于等于3个
    [ $# -gt 1 -a $# -le 3 ]
    [ $# -gt 1 ] && [ $# -le 3 ]
    

    条件判断,控制结构

    单分支if语句

    if [ -f abc ]; then
        echo "hello woeld"
        ......
    fi
    

    双分支if语句

    if [ -f abc ]; then
        echo "hello woeld"
    else
        echo "此文件不存在"
    fi
    

    多分支if语句

    if [ $i -gt 5 ]; then
        echo "大于5的数"
       
    elif [ $i -lt 3 ]; then
        echo "小于3的数"
    else
        echo "大于等于3,小于等于5的数"
    fi
    

    分支选择

    case $1 in            
        'start')                
            /usr/local/httpd/bin/apachectl start            
        ;;            
        'stop')                
            /usr/local/httpd/bin/apachectl stop             
        ;;  
         'restart')                
            /usr/local/httpd/bin/apachectl restart             
        ;;   
         'status')                
            status=$(ps -ef | grep -Ev "grep|$0|service httpd status"|grep httpd | wc -l)
            if [ $status -ne 0 ];then
                echo "httpd is running"
                else
                    echo "httpd is stopped"
            fi
        ;;                 
    *)                
            echo "Usage:service $0 start|stop|status"
            ;;
    esac
    
    • case支持glob风格的通配符:
      • * 任意长度任意字符
      • ? 任意单个字符
      • [] 指字范围内的任意单个字符
      • abc|bcd abc或bcd

    在RHCE中会有一道脚本的考试题目,很简单,就是使用case语句。而且为了防止我们在做服务的时候,重启之后客户机无法挂在,通常会写一个自动挂载的脚本,与上面的代码相似。

    循环语句

    • 循环语句通常需要有一个进入条件和一个退出条件

    for循环

    • for循环当列表不为空时进入循环,否则退出循环
    for (( expr1 ; expr2 ; expr3 ));do
        循环体
    done
    
    for ((expr1;expr2;expr3))
    {
        循环体
    }
    
    for i in $(seq 1 2 100); do   //i从后面的列表中取,1-100每隔2个数取一个数
        echo $i
    done
    
    for ((i=0;i<=3;i++))
    {
        echo $i
    }
    
    for (( i=0;i<=3;i++ ));do
        echo $i
    done
    
    • expr1 //用于指定初始条件,给控制变量一个初始值
    • expr2 //判定什么时候退出循环
    • expr3 //修正expr1指定的变量的值
    • 如何生成列表:
      • {1…100}
      • seq [起始数] [步进长度] 结束数

    while循环

    • while循环适用于循环次数未知的场景,注意要有退出条件。
    • 条件满足时进入循环,条件不满足了退出循环
    1. while循环正常用法
    while 条件; do
        statement
        ...
    done
    
    1. while循环特殊用法
    • while循环特殊用法一:死循环
    while :;do  //这里的冒号可以改成任何非空值
        statement
        ...
    done
    
    • while循环特殊用法二:逐行读取某文件,将值存入line变量中
    while read line;do
        statement
        ...
    done < /path/to/somefile
    
    • condition 表示判断条件
    • statements 表示要执行的语句(可以只有一条,也可以有多条),dodone都是 Shell中的关键字
    • while循环的执行流程为:
      • 先对condition进行判断,如果该条件成立,就进入循环,执行 while循环体中的语句,也就是dodone之间的语句。这样就完成了一次循环。
      • 每一次执行到 done的时候都会重新判断condition是否成立,如果成立,就进入下一次循环,继续执行 dodone之间的语句,如果不成立,就结束整个while循环,执行done后面的其它 Shell代码。
      • 如果一开始 condition 就不成立,那么程序就不会进入循环体,dodone 之间的语句就没有执行的机会。

    until循环

    • 条件不满足时进入循环,条件满足了退出循环
    until 条件; do
        statement
        ...
    done
    
    [root@bad test]# vim 1.sh
    #!/bin/bash
    until [ 4 -eq 5 ]   //4等于5不满足,进入循环
    do
        echo "hello"
        break
    done
    [root@RedHat test]# bash 1.sh
    hello
    

    循环语句特殊情况

    • 在循环语句中,有几种特别情况:
    break [num]    //提前退出循环。当循环语句中出现break时,将提前退出循环,不再执行循环后面的语句
    continue [num]    //提前结束本轮循环而进入下一轮循环。当循环语句执行到continue时,continue后面的语句将不再执行,提前进入下一轮循环
    
    
    break    //命令用于跳出循环,使用break可以跳出任何类型的循环:for、while、until
    continue    //命令用于中止本次循环,重新判断循环条件,开始下一次循环。
    exit    //退出脚本
    

    定义脚本退出状态码

    • exit命令用于定义执行状态结果
      • exit # 此处的#号是一个数字,其范围可以是0-255
    • 如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码
    • 注意:脚本中一旦遇到exit命令,脚本会立即终止
    以上内容均属原创,如有不详或错误,敬请指出。
    
    本文作者: 坏坏
  • 相关阅读:
    IO 模型知多少 | 代码篇
    IO 模型知多少 | 理论篇
    ASP.NET Core 反向代理部署知多少
    ASP.NET Core 借助 Helm 部署应用至K8S
    Orleans 知多少 | 4. 有状态的Grain
    Goodbye 2019,Welcome 2020 | 沉淀 2020
    Orleans 知多少 | 3. Hello Orleans
    集群环境下,你不得不注意的ASP.NET Core Data Protection 机制
    .NET Core 使用 K8S ConfigMap的正确姿势
    ASP.NET Core知多少(13):路由重写及重定向
  • 原文地址:https://www.cnblogs.com/bad5/p/12466529.html
Copyright © 2011-2022 走看看