shell脚本-基础

shell脚本-基础

编程基础

    程序是指令+ 数据
    程序编程风格:
        过程式:以指令为中心,数据服务于指令
        对象式:以数据为中心,指令服务于数据
    shell 程序提供了编程能力,解释执行。
    计算运行二进制指令。
    编译执行:
        高级语言--> 编译器--> 目标代码
        如java,C#
    解释执行:
        高级语言--> 解释器--> 机器代码
        如shell, perl, python
        
    编程逻辑处理方式:
        顺序执行
        循环执行
        选择执行
    
    shell 编程:
        过程式、解释执行
        
    编程语言的基本结构:
        各种系统命令的组合
        数据存储:变量、数组等
        表达式: a + b等
        语句:if的等

shell脚本说明

    shell 脚本:
        包含一些命令或声明,并符合一定格式的文本文件
    shell 脚本的用途有:
        自动化常用命令
        执行系统管理和故障排除
        创建简单的应用程序
        处理文本或文件
    格式要求:
        首行shebang 机制
        #!/bin/bash
        #!/usr/bin/python
        #!/usr/bin/perl
        ....
        #! 就是告诉系统,这个脚本文件需要使用指定的命令解释器来执行。
        紧随 #!的是一个路径名,此路径指向用来解释此脚本的程序,它可以是shell,可以是程序设计语言,也可以是实用程序。
        这个解释器从头( #!的下一行)开始执行整个脚本的命令,同时忽略注释。 
    shell脚本的创建和运行:
        创建脚本:
            使用文本编辑器vim等来创建文本。
            第一行必须是shell声明序列#!,一般为#!/bin/bash。
            其余行为执行的命令。
            添加注释使用#,注释以#开头。
        运行脚本:
            给予执行权限,在命令行上指定脚本的绝对或相对路径
                chmod +x FILE.sh
                /PATH/TO/FILE.sh
            直接运行解释器,将脚本作为解释器程序的参数运行
                source or . +脚本,一般不这么用,这样会对当前环境进行影响
                bash + 脚本,就不会影响外部工作环境
    脚本规范:
        脚本代码开头约定
            1 、第一行一般为调用使用的语言
            2 、程序名,避免更改文件名为无法找到正确的文件
            3 、版本号
            4 、更改后的时间
            5 、作者相关信息
            6 、该程序的作用,及注意事项
            7 、最后是各版本的更新简要说明
        脚本开头的示例:
            #!/bin/bash
            #-------------------------------------------------
            #Filename:
            #Description:
            #Revision:
            #Date:
            #Author:
            #Email:
            #Phonenumb:
            #Copyright:
            #------------------------------------------------
        脚本结构:
            解释器:#!/bin/shell,等
            配置变量:自己定义的变量,A=123等
            功能描述:以#开头来说明接下来执行语句的作用
            执行命令:指令+参数,包括各种语句表达式等
    脚本调试:
        检测脚本中的语法错误
            bash -n /PATH/TO/FILE.sh
        调试执行
            bash -x /PATH/TO/FILE.sh
        脚本中默认不支持别名
            尽可能用命令的绝对路径

变量介绍

    变量的作用:
        数据暂存
        参与运算
        表示数据范围
    强类型变量:
        变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。
        一般定义变量时必须指定类型、参与运算必须符合类型要求。
        调用未声明变量会产生错误。
        如 java,c#的变量
    弱类型变量:
        语言的运行时会隐式做数据类型转换。
        无须指定类型,默认均为字符型。
        参与运算会自动进行隐式类型转换。
        变量无须事先定义可直接调用
        如bash,php的变量
    变量的命名规则:
        不能使程序中的保留字,如if、for等。
        只能使用数字、字母及下划线,且不能以数字开头。
        需见名知义。
        统一命名规则,即驼峰命名法
    bash中的变量种类
        根据变量的生效范围作为标准
        本地变量:   生效范围为当前shell进程。对当前shell之外的其它shell 进程,包括当前shell的子shell 进程均无效。
        环境变量:   生效范围为当前shell进程及其子进程。
        局部变量:   生效范围为当前shell进程中某代码片断( 通常指函数)。
        位置变量:   $1, $2, ...来表示,用于让脚本在脚本代码中通过调用命令行传递给它的参数,大于9的数,就应该加大括号:${10}
        特殊变量:   $?, $0, $*, $@, $#,$$
    本地变量
        变量赋值:
            name=value
        引用value:
            直接字串:   name=“root"
            变量引用:   name="$USER"
            命令引用:   name=` COMMAND `; name =$(COMMAND)
        变量引用:
            ${name}  
            $name   
            "  " :  弱引用,其中的变量引用会被替换为变量值
             '  ':  强引用,其中的变量引用不会被替换为变量值,而保持原字符串
            ${name[$i]} i是变量,name[$i]也是变量
            ' ':最傻的那个 ;" ":中间傻 ; ` `:聪明
        显示已定义的所有变量:
            set
        删除变量:
            unset name
    环境变量
        变量声明和赋值:
            export  name=VALUE
            declare -x  name=VALUE
        变量引用:
            $name, ${name},"$name"(尽量用带括和带双引号的)
        显示所有环境变量:
            env
            printenv
        bash内建的环境变量
            PATH,SHELL,USER,UID,HOME,PWD,SHLVL,LANG,MAIL,HOSTNAME,HISTSIZE,—
    只读变量
        只能声明,但不能修改和删除。
        声明只读变量:
            readonly name
            declare -r name
                先赋值再声明或者是声明赋值一起做,不然,声明过后就不能再赋值了
        查看只读变量:
            readonly –p
    位置变量
        在脚本代码中调用通过命令行传递给脚本的参数
        $1, $2, ... :   对应第1 、第2 等参数,是脚本后面跟着的参数,且9以后需要加大括号:${10}
        shift [n]   可以更换位置
        $0:     命令本身
        $*:     传递给脚本的所有参数,全部参数合为一个字符串
        $@:     传递给脚本的所有参数,每个参数为独立字符串
        $#:     传递给脚本的参数的个数
        $@与$*   只在被双引号包起来的时候才会有差异
        set - -     清空所有位置变量
        涉及到位置参数,脚本前面放置这个
            [ $# -lt 1 ] && echo "Usage:`basename $0` arg1... " && exit 10
            
    转换变量类型
        可以使用declare或者typeset来转换变量类型
            [root@localhost ~]# a=1;b=2;c=a+b;
            [root@localhost ~]# echo $c
            a+b
            [root@localhost ~]# typeset -i a;typeset -i b;typeset -i c;
            [root@localhost ~]# a=1;b=2;c=a+b;
            [root@localhost ~]# echo $c

退出状态

    进程使用退出状态来报告成功或失败
    0 代表成功,1 -255 代表失败
    $?变量保存最近的命令退出状态
    示例:
        ping -c1 -W1 hostdown &> /dev/null
        echo $?
    bash 自定义退出状态码
        exit [n]:自定义退出状态码
        注意:
            脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit 命令后面的数字
            如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

算术运算

    help let
    let arg [arg ...]
    运算
        +, -, *, /, % 取模(取余), ** (乘方)
        注:乘法符号有些场景中需要转义 , 如*
    增强型赋值:
        +=, -=, *=, /=, %=
    自增和自减:
        let var+=1
        let var++
        let var-=1
        let var--
    实现算术运算
        let var= 算术表达式
        var=$[ 算术表达式]
        var=$(( 算术表达式))
        var=$(expr arg1 arg2 arg3 ...)    ##expr判断后面的变量是否为整数,但不能为0。
        declare –i var =  数值
        echo ‘ 算术表达式’ | bc
        bc
        $RANDOM (0-32767)  ##bash内建的随机数生成器
            echo $[$RANDOM%50]  ##0-49 之间随机数

逻辑运算

    true和false
        1, 0
        输出0为假
        设置空为假
        设置0为真
    与:
        1  与 1 = 1
        1  与 0 = 0
        0  与 1 = 0
        0  与 0 = 0
    或:
        1 或  1 = 1
        1 或  0 = 1
        0 或  1 = 1
        0 或  0 = 0
    非:!
        ! 1 = 0
        ! 0 = 1
    短路运算
        短路与
        第一个为0 ,结果必定为0
        第一个为1 ,第二个必须要参与运算
        短路或
        第一个为1 ,结果必定为1
        第一个为0 ,第二个必须要参与运算
    
    异或:^
        异或的两个值, 相同为假,不同为真
        数值交换:       

1250974-20180207000553779-1074098360.png

条件性执行操作符:&&和||

    根据退出状态而定,命令可以有条件地运行。
    &&  代表条件性的and、then,与
    || 代表条件性的or、else,或

条件测试:

    判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程
    评估布尔声明,以便用在条件性执行中
        若真,则返回0
        若假,则返回1
    测试命令和表达式
        test EXPRESSION    
        [ EXPRESSION ]
        [[ EXPRESSION ]]     ##支持扩展的正则表达式算法
        注意:
            EXPRESSION 前后必须有空白字符
            多测试在使用
            ![](http://images2017.cnblogs.com/blog/1250974/201802/1250974-20180207000632435-1219260200.png)
    
    数值测试:
        -gt (great than)    大于
        -ge (great equal)   大于等于
        -eq  (equal)    等于
        -ne (not equal) 不等于
        -lt (lower than)    小于 
        -le (lower equal)   小于等于
    字符串测试:
        ==  等于
        >   ascii 码大于ascii码 
        <   小于
        !=  不等于
        =~  左侧字符串能够被右侧的PATTERN所匹配
        -z  "STRING“ 字符串为空,空为真,不空为假
        -n  "STRING“ 字符串不空,不空为真,空为假
        注意:  
            此表达式一般用于[[ ]] 中;扩展的正则表达式。
            用于字符串比较时,用到的操作数STRING都应该使用引号。
    文件测试
        存在为真,不存在为假
        存在性和类别测试:
            -a|-e FILE:     是否文件存在
            -b FILE :   是否存在且为块设备文件
            -c FILE :   是否存在且为字符设备文件
            -d FILE :   是否存在且为目录文件
            -f FILE :   是否存在且为普通文件
            -h|-L FILE :    存在且为符号链接文件
            -p FILE :   是否存在且为命名管道文件
            -S FILE :   是否存在且为套接字文件
        文件权限测试:
            -r FILE :   是否存在且可读
            -w FILE:    是否存在且可写
            -x FILE:    是否存在且可执行
            测试的是实际权限,例如root就有大多数权限
        文件特殊权限测试:
            -u FILE :   是否存在且拥有suid 权限
            -g FILE :   是否存在且拥有sgid 权限
            -k FILE :   是否存在且拥有sticky 权限
        文件大小测试:
            -s FILE:    是否存在且非空
        文件是否打开:
            -t fd:  fd表示文件描述符是否已经打开且与某终端相关
            -N FILE:    文件自从上一次被读取之后是否被修改过
            -O FILE :   当前有效用户是否为文件属主
            -G FILE :   当前有效用户是否为文件属组
        双目测试:
            FILE1 -ef FILE2:    FILE1与FILE2 是否指向同一个设备上的相同inode
            FILE1 -nt FILE2:    FILE1是否新于FILE2 (mtime) 
            FILE1 -ot FILE2:    FILE1是否旧于FILE2
        
    组合测试
        命令
            COMMAND1 && COMMAND2     并且
            COMMAND1 || COMMAND2     或者
            ! COMMAND    非
            如:[[ -r FILE ]] && [[ -w FILE ]]
        表达式
            EXPRESSION1 -a EXPRESSION2      并且
            EXPRESSION1 -o EXPRESSION2      或者
            ! EXPRESSION    非
            必须使用测试命令进行
        示例:
            [ -z “$HOSTNAME” -o $HOSTNAME "=="localhost.localdomain" ] && hostname shen
            [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

括号的用法

    小括号()
        (子进程),小括号是开子进程了,开子shell,小括号内值,只能在括号内用。
    中括号[ ]
        [表达式],用于测试
    大括号{ }
        { cmd ; cmd ; …. ; }不会开子shell

参数导入:read

    使用read 来把输入值分配给一个或多个shell 变量。
    使用read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量。
    示例:
        read -p “Enter a filename: “  FILE
        read a b c <<< "xxx yyy zzz"

展开命令行的优先级

    优先级从高到低
    把命令行分成单个命令词
    展开别名
    展开大括号的声明({}) 
    展开波浪符声明(~) 
    命令替换$() 和 (``) 
    再次把命令行分成命令词
    展开文件通配(* 、? 、[abc] 等等)
    准备I/0 重导向(< 、>) 
    运行命令

防参数属性扩展

    反斜线(\ )会使随后的字符按原意解释
        $ echo Your cost: \$5.00
        Your cost: $5.00
    加引号来防止扩展
        单引号(’ )防止所有扩展
        双引号(” )也防止所有扩展,但是以下情况例外:
            $ (美元符号)#变量扩展
             ` (反引号)#命令替换
            \ (反斜线) #禁止单个字符扩展
            ! (叹号)#历史命令替换

$- 变量

    echo $-
    himBH
    h:hashall ,
        打开这个选项后,Shell会将命令所在的路径hash下来,避免每次都要查询,通过set +h 将h 选项关闭。
    i:interactive-comments,
        包含这个选项说明当前的shell的是一个交互式的 shell ,所谓的交互式shell, 在脚本中i 选项是关闭的。
    m:monitor,
        打开监控模式,就可以通过Job control 来控制进程的停止、继续,后台或者前台执行等。
    B:braceexpand ,
        大括号扩展
    H:history ,
        H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!” 返回上最近的一个历史命令,“!n”第 返回第 n个历史命令

转载于:https://www.cnblogs.com/shenxm/p/8424816.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值