bash脚本编程基础

bash编程  
bash脚本编程是过程式解释编程,其实就是linux命令的堆砌,既然是编程就应该有相应编程语法。    
与任何过程式编程一样,过程式编程的特点就是:顺序执行,选择执行,循环执行。    
过程式编程:以指令为中心,设计算法,数据服务于算法,过程式编程的灵魂:算法。    
1.变量:数值变量,字符变量    
       bash环境:    
            本地变量:当前shell进程;    
            环境变量:当前shell进程及其子进程;    
            局部变量:某个函数执行过程;    
            位置参数变量:在脚本中引用传递给脚本的参数;在函数中引用传递给函数的参数;    
            特殊变量:$? :上一条命令的执行状态结果    
                            $*, $@:引用传递给脚本或函数的参数列表    
                            $#:传递给脚本或函数的参数的个数    
                            $$    
1.1bash的变量使用特点:弱类型、无须事先声明;

        定义变量名:只能包含数字、字母和下划线;且不能以数字开头;  
                引用变量:${name}, $name    
       引用:    
                弱引用: "", 其内部的变量引用会被替换为变量值;注意:字符变量常用    
                强引用:' ',其变量的变量引用会保持原有字符;    
                命令引用:`COMMAND`, $(COMMAND),引用命令的执行结果;常用 $(COMMAND)

bash变量默认是字符  
               数值变量,声明为整型:    
                declare -i name[=value]    
                let name=value    
               
                查看所有变量:set    
销毁变量:    
                    自动销毁:shell进程终止;    
                    手动销毁:unset name

环境变量:  
            被“导出”的本地变量    
                export name[=value]    
                declare -x name[=value]

            查看所有环境变量:env, printenv, export

            销毁环境变量:  
                unset name       
               
bash脚本编程,其实就是文本文件,要运行脚本,其实就是运行一个bash进程,由bash进程解释并运行。    
启动脚本:    
            (1) # bash /PATH/TO/SCRIPT_FILE    
            (2) 给bash脚本一个执行权限, 在命令行输入:    
                # ./PATH/TO/SCRIPT_FILE

                shebang:语法,脚本文件顶格输入 #!/bin/bash  
               
        第一行:顶格给出shebang    
        注释行:#

        bash的常用选项:  
            -n: 检查脚本中的语法错误;    
            -x:调试执行脚本;

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":是否不空;不空则“真”,空则为“假”

            注意:应该使用[[ EXPRESSION ]]

文件测试:测试文件的存在性以及属性;  
            -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的最近一次的修改时间戳是否晚于file2的;    
            $file1 -ot $file2: file1是否旧于file2, file1的最近一次的修改时间戳是否早于file2的;    
            $file1 -ef $file2:file1与file2是否指向了同一个inode;测试二者是否为同一个文件的硬链接;    
       
特殊设备:    
        /dev/null: 空,bit buckets,吞下所有数据,并直接丢弃;    
        /dev/zero:吐出一堆0;

脚本参数(位置参数变量):  
        # ./script.sh /etc/fstab /etc/grub2.cfg    
              $0          $1          $2

        位置参数变量:$1, $2, ...  
            ${10}

        特殊变量:  
            $?: 命令的状态结果;    
            $#: 传递给脚本或函数的参数的个数;    
            $*和$@: 引用传递给脚本或函数的参数列表;

        shift [n]:轮替

与用户交互:  
        read命令:    
            read [options] VAR...    
                -p "PROMPT"    
                -t timeout

命令引用:  
        `COMMAND`, $(COMMAND)

        引用命令的执行结果;

算术运算:  
        +, -, *, /, %, **

        (1) $[$A+$B]  
        (2) $(($A+$B))    
        (3) let VARIABLE=$A+$B    
        (4) VARIABLE=$(expr $A + $B)       

增强型赋值:  
        +=    
            sum=$[$sum+$i]    
            let sum+=$i

        -=, *=, /=, %=

            let count=$[$count+1]   --> let count+=1 --> let count++  
            let count=$[$count-1] --> let count-=1 --> let count--

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

        注意:  
            (1) 字符串等会比较测试:[ "$hostname" == 'localhost'  ]    
            (2) 模式匹配测试:[[ "STRING" =~ PATTERN ]]

组合测试条件:  
            条件间逻辑运算:    
                与:多个条件要同时满足;    
                或:多个条件满足其一即可;    
                非:对指定的条件取反;

            表达式组合:  
                与:[[ CONDITION1 -a CONDITION2 ]]    
                或:[[ CONDITION1 -o CONDITION2 ]]    
                非:[ ! CONDITION ]

            命令组合:  
                与:COMMAND1 && COMMAND2  <-- [ EXPR1 ] && [ EXPR2 ]    
                或:COMMAND1 || COMMAND2    
                非:! COMMAND

            短路操作符:&&  
                    false && true = false    
                    false && false = false

                    true && false = true  
                    true && true = true

                    if COMMAND1; then  
                        COMMAND2    
                    fi

            短路操作符:||  
                    true || true = true    
                    true || false = true

                    false || true = true  
                    false || false = false

                if ! COMMAND1; then  
                    COMMAND2    
                fi

                COMMAND1 && COMMAND2 || COMMAND3  
                    if COMMAND1; then    
                        COMMAND2    
                    else    
                        COMMAND3    
                    fi           

流程控制:选择执行和循环语句  
           
多分支的if语句:    
        单分支:    
            if CONDITION; then    
                if-true-分支    
            fi

        双分支:  
            if CONDITION; then    
                if-true-分支    
            else    
                if-false-分支    
            fi

        多分支:  
            if CONDITION1; then    
                if-CONDITION1-true-分支    
            elif CONDTION2; then    
                if-CONDITIO2-true-分支    
            ...    
            else    
                if-ALL-false-分支    
            fi

! CONDITION: 取反   

case语句  
        简洁版多分支if语句;               
        使用场景:判断某变量的值是否为多种情形中的一种时使用;

        语法:  
            case $VARIABLE in    
            PATTERN1)    
                分支1    
                ;;    
            PATTERN2)    
                分支2    
                ;;    
            PATTERN3)    
                分支3    
                ;;    
            ...    
            *)    
                分支n    
                ;;    
            esac

            PATTERN可使用glob模式的通配符:  
                *: 任意长度的任意字符;    
                ?: 任意单个字符;    
                []: 指定范围内的任意单个字符;    
                a|b: 多选1;       
   
   
       
        循环语句:for, while, until

        for循环:将循环体代码执行0、1或多次;  
            进入条件:进入循环的条件;    
            退出条件:循环终止的条件;

        for VARIABLE in LIST; do  
            循环体    
        done

        LIST:是由一个或多个空格或换行符分隔开的字符串组成;  
            把列表的每个字符串逐个赋值给VARIABLE表示的变量;

            for username in user1 user2 user3; do  
                循环体    
            done

            进入条件:列表非空;  
            退出条件:列表遍历结束;    
       
        while循环:

            while CONDTION; do  
                循环体    
            done

            进入条件:当CONDITION为“真”;  
            退出条件:当CONDITION为“假”;

            while CONDITION; do  
                循环体    
                控制变量的修正表达式    
            done    
       
        unitl循环:    
            until CONDITION; do    
                循环体    
                循环控制变量的修正表达式    
            done

            进入条件:当CONDITION为“假”时  
            退出条件:当CONDITION为“真”时   

死循环:  
            while true; do    
                循环体    
                if CONDTION; then    
                    break    
                fi    
            done

            until false; do  
                循环体    
                if CONDITION; then    
                    break    
                fi    
            done

函数:  
既模块化编程    
            功能:把脚本文件中的代码分隔为多段,放在不同的文件中    
                假设/root/bin/srv目录有两个文件:    
                (1) 函数文件    
                (2) 脚本文件

        为脚本使用配置文件  
            一个文件中只定义变量    
            脚本文件source此变量定义的文件

        变量的作用域:  
            局部变量:    
                local VARIABLE=value

            存活时间:  
                函数执行开始,至函数返回结束;

        function: 功能  
            把一段具有独立功能代码封装在一起,并给予命名;后续用到时,可直接通过给定函数名来调用整体代码;

            函数作用:  
                代码重用;    
                模块化编程;

        函数的使用方法:  
            先定义:编写函数代码    
            后调用:给出函数名,还可按需传递参数

        定义方法:  
            (1) function f_name {    
                    函数体    
                }

            (2) f_name() {  
                    函数体    
                }

        调用函数:  
            f_name [argu1, argu2, ...]

        自定义函数状态返回值:  
            return [#]    
                0: 成功    
                1-255:失败

            注意:函数代码执行时,一旦遇到return,函数代码终止运行,函数返回;  
           
练习:    
1、写一个脚本:如果某路径不存在,则将其创建为目录;否则显示其存在,并显示内容类型;(不要怀疑,就是这么简单)

 

wKiom1YDUVnj0M1wAACdaRw-aoA042.jpg

 

wKioL1YDUVyTRFK_AAKnw8S6F1Q517.jpg

 


2、写一个脚本,完成如下功能;判断给定的两个数值,孰大孰小;给定数值的方法:脚本参数,命令交互;(使用read,依然如此简单)

 

wKioL1YDc0eycbJkAADgFkVEq0g685.jpg

 

wKioL1YDc0iCkWYkAAFnKqsRDNA176.jpg

 

3、求100以内所有奇数之和(至少用3种方法。是的这是我们的作业^_^)

 

wKiom1YDjDfyjs8sAABTXsX1c-0384.jpg

 

wKioL1YDjDqA8dm3AABl5mUO-CA364.jpg

 

wKioL1YDjDqi7GtIAABgobTTs_s328.jpg

 

wKiom1YDkaOQlwF3AAB07vA-7sk691.jpg

 

4、写一个脚本实现如下功能:

(1) 传递两个文本文件路径给脚本;

(2) 显示两个文件中空白行数较多的文件及其空白行的个数;

(3) 显示两个文件中总行数较多的文件及其总行数;

wKiom1YDvdrQnBg5AAKQQcxZFhk975.jpg

 

wKioL1YDvd2zaUF3AAExsKnD5kY705.jpg

wKiom1YDvdqh8325AABgj8_gpOY964.jpg

 

5、写一个脚本

(1) 提示用户输入一个字符串;

(2) 判断:

如果输入的是quit,则退出脚本;

否则,则显示其输入的字符串内容;

 

wKioL1YDwIyyWZ5EAACUD-5wTU4296.jpg

 

wKiom1YDwInBSUS3AAEDCuLyTQY078.jpg

 

6、写一个脚本,打印2^n表;n等于一个用户输入的值;(不好意思,我调皮了)

 

wKioL1YDz2fB29RHAADnXWSA4nE288.jpg

 

wKiom1YDz2TBvAgFAABacoEK1yw221.jpg

 

wKioL1YD0g6gG3TGAABlUj3etRk067.jpg

 

wKioL1YD0g7BFAsEAABZgBUT38c591.jpg

 

 

7、写一个脚本,写这么几个函数:函数1、实现给定的两个数值的之和;函数2、取给定两个数值的最大公约数;函数3、取给定两个数值的最小公倍数;关于函数的选定、两个数值的大小都将通过交互式输入来提供。

 

 

你可能感兴趣的:(bash编程)