linux下的bash编程简要学习

    

    1.bash是什么:

        linux运行时系统只会运行系统运行所需要的运行脚本即系统守护进程,一般根据用户自己需求设定和实现的服务需要手动启动,这种服务进程通常由bash启动,脚本中的命令通常被按照一定规则被bash读取视作参数,因此在脚本头部要申明运行的bash类型,bash命令分为内建命令及外部命令,外部命令通过PATH进行依次查找。

        bash读取命令后将其启动(fork)成为一个进程,依次启动服务

    2.bash控制语句:

        本地变量:当前shell

        环境变量:当前shell及其子shell

        局部变量:某个函数内

        位置变量:脚本或函数中引用传递参数

        特殊变量

                    $# 是传给脚本的参数个数
                    $0 是脚本本身的名字
                    $1 是传递给该shell脚本的第一个参数
                    $2 是传递给该shell脚本的第二个参数
                    $@ 是传给脚本的所有参数的列表
                    $* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
                    $$ 是脚本运行的当前进程ID号
                    $? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

===========================================================

TEST1:

        wKiom1X6cBTzaFtPAADQgoXn3cY195.jpg

    变量:

            变量类型决定了变量一下三个点:

                    1.存储空间(存储数据空间)

                    2.参与运算类型

                    3.存储格式

    变量引用:

            变量引用分为一下三种方式:

                    1.强引用''

                    2.弱引用""

                    3.命令引用$(COMMAND),`COMMAND`

===========================================================

Test2

                wKiom1X6cVrSAXsTAADE6Bojzm8355.jpg


    变量申明:

            申明整型变量(默认为字符变量):
                
declare -i name[=value]
                let name=value

    
            环境变量:
                
export name[=value]
                declare -x name[=value]
                env,printenv,export查看全部环境变量
                set可以查看全部变量

    bash执行:

                bash -n 检查脚本中语法错误
                         -x  调试脚本
                可通过exit [n]更改命令返回值,exit会结束当前进程


    bash控制:

        条件判断:
                通过控制条件实现程序的选择执行
                1.根据运行命令的执行结果
                2.测试表达式:
                    test EXPRESSION
                    [ EXPRESSION ]
                    ` EXPRESSION `

        整数测试:
                $A -gt $B:是否大于
                $A -ge $B:是否大于等于
                $A -lt $B:是否小于
                $A -le $B:是否小于等于
                $A -eq $B:是否等于
                $A -ne $B:是否不等
                注意:整数测试默认做数值大小比较,所以不要给变量加引号

        字符串测试:
                字符串比较通过逐个字符的ASCII码值进行比较
                "$A" > "$B":是否大于
                "$A" < "$B":是否小于
                "$A" == "$B":是否等于
                "$A" != "$B":是否布冯
                -z "$A" :是否为空,空为真
                -n "$A" :是否不为空,不空为真


        文件测试:
               测试文件存在,存在状态及属性
                -e $file:是否存在,存在为空
                -a $file:是否存在,存在为空
                -f $file:文件是否存在且为普通文件
                -d $file:文件是否存在且为目录
                -h $file:是否存在且为符号链接
                -L $file:是否存在且为符号链接
                -b $file:是否存在且为块设备文件
                -c $file:是否存在且为字符文件设备
                -S $file:是否存在且为套接字文件设备
                -p $file:是否存在且为管道文件
    
                -r $file:当前用户是否对文件拥有读权限
                -w $file:当前用户是否对文件拥有写权限
                -x $file:当前用户是否对文件拥有执行权限
    
                -u $file:文件是否具备SUID权限
                -g $file:文件是否具备SGID权限
                -k $file:文件是否具备sticky权限
    
                -O $file:当前用户是否为指定文件属主
                -G $file:当前用户是否为指定文件属组


    双目操作符:
                $file1 -nt $file2:file1是否新于file2,比较时间为最近一次修改时间戳
                $file1 -ot $file2:file1是否旧于,file1的最近一次修改时间是否早于file2
                $file1 -ef $file2:file1与file2是否指向了同一个inode,是否为一个文件硬链接

  

     条件控制:

                if/then,case(PATTERN可为glob模式)

                if CONDITION;then                    case $VARIBLE in
                        语句                                     PATTERN1)
                fi                                                        分支1
                                                                            ;;
                if CONDITION;then                  PATTERN2)
                        语句                                             分支2
                else                                                      ;;
                        语句                                    esac
                fi

======================================================

**TEST3作业5:写一个脚本,若路径不存在则将其创建为目录,否则则显示其存在及内容类型

    wKioL1X6dhmSACSQAACGmP5LCWA795.jpg

TEST4shift

    wKioL1X6dnLS9zcoAAAulvwXH-g618.jpg

wKioL1X6hh7y-M7IAACF75-LxyM143.jpg

      read:

        read:与用户交互命令:
            主要参数 -p "message":message显示给终端
                           -t #:多少秒内未输入自动退出
        read a b  直接从键盘上读取数据,空格分开

==================================================

**TEST5作业6:写一个脚本,完成如下功能;判断给定的两个数值,孰大孰小;给定数值的方法:脚本参数,命令交互;

wKioL1X6hofQx1HQAADF29w9oZI314.jpg

      循环控制:

        for,while,until

        for:

        while:

            while CONDITION;do

                循环体

            done

            当condition为真时执行,反之则退出

        until:

            until CONDITION;do

                循环体

            done

            当CONDITION为假时执行,反之则退出

        continue:跳出本次循环执行下次循环

        break:直接退出循环

    测试表达式(CONDITIDON):

        整数测试:-gt,-lt,-ge,-le,-eq,-ne
        字符串测试:==,<,>,!=,-z,-n,=~

    注意格式: [ "hostname" == "localhost" ]
                      [[ "STRING" =~ PATTERN ]]

    算术运算方式
        $[$A+$B]
        $(($A+$B))
        let variable=$A+$B
        variable=$(expr $A + $B)

===========================================

用for,while,until三种方法求1-100和:

for:

wKioL1X6ioXB6GVkAABCATKK3OE581.jpg

while:

wKiom1X6ibHSNkOoAABVywvr2WA680.jpg

until:

wKioL1X6jPbxBy5BAABMpnFz0wg125.jpg


**TEST作业7三种方式求100以内所有奇数之和

wKioL1X6qgKCyzspAAD4Pehh2uE928.jpg


    组合测试条件:
        条件间逻辑运算:
            与:多个条件同时满足
            或:多个条件满足一个条件即可
            非:对指定条件取反
        表达式组合:
            与:` CONDITION1 -a CONDITION2 `
            或:` CONDITION1 -o CONDITION2 `
            非:[ ! CONDITION ]

        
    短路操作符:
    COMMAND1 && COMMAND2 || COMMAND3


===========================================

TEST6:获取当前主机hostname,若为空或localhost,则修改为admin

    wKioL1X6hsWzqGEsAABcVEH8bH8724.jpg

**TEST7作业8:传递两个文本文件路径给脚本,显示两文件中空白行较多的文件和其空白行数

                显示两个文件中文件行数较多的文件及其总行数


wKioL1X6hu3y9INiAAGA5FK2_m8869.jpg

TEST8:99乘法表:

    wKiom1X6hULhEXdpAABEY5ovoUQ596.jpg

**TEST作业9

wKiom1X6qajih8VEAAB0vH6RYV4128.jpg

**TEST作业10

wKiom1X6znbgRj7CAACKkHf3l8U127.jpg

wKioL1X60bXALhWFAAA4wPZ338Q482.jpg


    function:

        为实现代码复用,模块化设计的代码块:

            函数申明格式:

            function f_name{

                函数体

                }

            f_name(){

                函数体

                }

        调用函数:

                f_name [argu1,argu2...]


        为脚本使用配置文件

            一个文件只定义变量

            脚本文件 source此变量定义文件

**TEST作业11:


wKioL1X70Izihx4xAAGk6Hp-56w302.jpg

wKioL1X70Izjgz6YAAFxPM_6ykU527.jpg

wKiom1X7zlPxP7SxAACkaTBXuGE803.jpg

    效果图:


wKiom1X7zoShzPtjAACbF5mugxc057.jpg

        图中个别为调试输出

sed:

    流编辑器功能:将数据一行行读入模式空间,修改后显示出来,默认不改动源文件

    格式:sed [OPTION]... {script} [input-file]...

                        -r: 支持扩展正则表达式;
                        -n: 静默模式;
                        -e script1 -e script2 -e script3:指定多脚本运行;
                        -f PATH:读取指定脚本并运行;
                        -i: sed改动时会改动源文件,慎用;

    

                地址定界:
                        #: 指定行;
                        $: 最后一行;
                        /PATTERN/:能够被PATTERN匹配到的行;
                        \%PATTERN%:用%作为边界符;
                        \%PATTERN%| 或者/PATTERN/|:匹配时忽略字符大小写;
                        startline,endline:
                            #,/PATTERN/:从#行开始,到第一次被/regexp/所匹配到的行结束,中间的所有行;
                            #1,#2:从第#1行到第#2行
                        /PATTERN1/,/PATTERN2/:从第一次被/PATTERN1/匹配到的行开始,到第一次被/rPATTERN2/匹配到的行结束,中间的所有行;
                            #,+n:从#行开始,到之后的n行;
                            first~step:指定起始行,以及步长;
                            1~2:第一行开始,步进为2读取

                sed命令:

                        a:新增,在当前行下一行添加

                        c:取代,c \text:用text替换匹配到的行

                        d:删除

                        i:当前行的上一行插入,i \text:插入text,支持\n实现多行插入;

                        p:输出匹配到的数据行

                        s:取代:s/pattern/取代后的内容/,加g表全局替换


                        w PATH:把检索内容另存至PATH路径所指定的文件中;
                        r PATH:在文件的指定位置插入另一个文件(PATH)的内容,完成文件合并;

TEST:

源文件:

    wKioL1X9bPvjLBYgAADCUDawe44848.jpg


只显示第1-3行:

    wKioL1X9bZ3TRxZjAACD6Zu0IL8359.jpg


第一行开始,隔行插入 ==============:

    wKioL1X9bljhf0CcAADnFTgrD4Y362.jpg

删除掉/sbin/nologin结尾的行:

    

wKiom1X9bIzQdvqmAAIMK86zcyo171.jpg


偶数行另存为/tmp/fstab1文件

wKiom1X9bVbxna83AACou537ZsY759.jpg

wKioL1X9b5HjK4BvAAD-ZLJQSS0916.jpg

    

            模式空间与保持空间:

                模式空间:直接编辑数据流,不存放中间数据

                保持空间:数据流临时存储,参照仓库

                

            sed空间命令:
                h:用模式空间中的内容覆盖保持空间的内容;
                H:把模式空间中的内容追加至保持空间中内容的后面;
                g:从保持空间中取到其内容,并将其覆盖模式空间中的内容;
                G:从保持空间中取到其内容,并将其追加在模式空间中的内容的后面;
                x:把保持空间和模式空间中的进行交换;
                n:读取匹配到的行的下一行至模式空间;(会覆盖模式空间中的原有内容);
                N:读取匹配到的行的下一行至模式空间,追加在模式空间中原有内容的后面;
                d:删除模式空间中的内容;
                D:删除多行模式空间中的首行;

            

                !表示地址取反,分号用于分隔命令

                   示例:
                        sed 'G' /etc/issue: 在文件中的每行后方添加空白行;
                        sed '$!d' /etc/fstab:保留最后一行;
                        sed '/^$/d;G' /etc/issue: 保证指定的文件每一行后方有且只有一个空白行;
                        sed 'n;d' /etc/issue:保留奇数行;
                        sed -n '1!G;h;$p' /etc/issue
                        sed '$!N;$!D' /etc/issue 

                    自己理解执行


awk:

        相较于sed,awk更倾向于将行分割成段后处理

        格式:awk [options] 'PATTERN{action}' file file ...

            -F CHAR:输入分隔符

            awk '条件类型{动作1} 条件类型{动作2}..'filename

        

        awk本质上将行分割为$0,$1...$NF

        awk内置变量:

            NF:每行的总字段数

            NR:目前处理的是第几行数据

            FNR:行数;各文件分别计数;

            FS:目前的分割符

            RS:输入时行分隔符

        

            OFS: Output Field Seperator, 输出时的字段分隔符;
            ORS: Outpput Row Seperator, 输出时的行分隔符;

    

        awk自定义变量:

            -v var_name=VALUE
            变量名区分字符大小写;
                (1) 可以program中定义变量;
                (2) 可以命令行中通过-v选项自定义变量;


        print和printf区别:

            printf需为后面参数输出指定format

    

        format格式的指示符都%开头,后跟一个字符:
            %c: 显示字符的ASCII码;
            %d, %i: 十进制整数;
            %e, %E: 科学计数法显示数值;
            %f: 显示浮点数;
            %g, %G: 以科学计数法格式或浮点数格式显示数值;
            %s: 显示字符串;
            %u: 显示无符号整数;
            %%: 显示%自身;


        format格式的指示符都%开头,后跟一个字符:
            %c: 显示字符的ASCII码;
            %d, %i: 十进制整数;
            %e, %E: 科学计数法显示数值;
            %f: 显示浮点数;
            %g, %G: 以科学计数法格式或浮点数格式显示数值;
            %s: 显示字符串;
            %u: 显示无符号整数;
            %%: 显示%自身;


        awk可根据自身需求设计编程:

            尚在学习中,近期学习整理后编辑上传

                    

       

TEST:

awk分割显示/etc/passwd中所有的用户名:

wKioL1X9dD7AhNmlAABjxH2UYV0667.jpg

取出/etc/passwd中用户名及其uid:

wKiom1X9cyLQQKtQAABcbVlJld0557.jpg

显示系统用户:

第一行不正常显示(不带begin):

wKiom1X9dTyggLKdAAB3L0gRt3s450.jpg

带BEGIN:

wKioL1X9d3fBQWhsAABtb1xvpHY664.jpg