Linux基础---1.4shell编程

一、shell是什么?

语言可以分为两类  编译型语言(C/C++) 以及解释型语言(shell,python,js)。同时shell是一个命令解析器(程序),可以解析用户的输入,交给操作系统内核执行,并且把结果反馈给用户,本身也是一个程序我们可以把很多需要执行的命令(操作),以一种语言的方式组织起来,交给SHELL去运行(解析)

shell脚本的解释器程序    

        cat /etc/shells   
        # /etc/shells: valid login shells
        /bin/sh
        /bin/bash           <---------
        /bin/rbash

目录

一、shell是什么?

1 写一个简单的脚本文件

2 shell中的变量的使用

3.shell数组

4.shell中的语句

    4.1说明性语句

    4.2功能性语句

            4.2.1.输入重定向 

            4.2.2.输出重定向 

            4.2.3.命令中的管道用法

            expr:执行算术运算符命令

            test:测试语句

                a.字符串测试   

                b.整数测试    

                c.文件测试   

    4.3结构性语句(分支语句/循环语句)

        a.分支语句    

        b.多路分支语句(switch)

        c.循环语句   

            for循环   

            while循环

            until循环

        d.break和continue 

5.shell中的函数 

5.1自定义函数的语法:

   5.2 函数的返回值的获取,通常有两种方式:

    5.2.1.通过反撇号获取命令/函数的执行结果

    5.2.2.使用位置变量$?


1 写一个简单的脚本文件

 shell脚本文件要以.sh结尾,其内容多为:

    #!/bin/bash 
    echo "hello shell"   

    第一行都是固定的:  #!/bin/bash 

    指定由/bin目录下面的哪一个解释器来解析这个脚本文件
    脚本中以#开头的行是注释(第一行除外)

    shell脚本是不需要编译的,可以直接解释运行,但是需要可执行权限
   

     chmod +x 01.sh 

    对于一个基础SHELL脚本文件要学习的语法有:
    1、变量的使用
    2、数组的使用
    3、语句(表达式/分支/循环)
    4、函数
 

2 shell中的变量的使用

shell变量没有类型的概念,都是字符串,变量也不需要定义,可以直接使用,shell变量一般有三种

自定义变量、位置变量、环境变量。

格式为:变量名=值           #=两边不能有空格

    name=zhangsan
    x=123
    x=abc
    ...

  如何引用变量:
        $变量名    or   ${变量名}

三种变量具体如下:


        1.自定义变量(自己定义的变量)
            例如:

            name=zhangsan
            x=123
            x=abc
            ...

            shell中可以使用普通的shell命令
            d=`date`   反撇号(esc的下面)
            作用:引用反撇号里面那一个“变量/命令/程序”的输出结果(原先输出到标准输出的内容)
            shell中的变量都是字符串,可以直接写到一起,表示连接
        2.位置变量
            相当于C语言里面main函数的argc和argv
            指的是传递给脚本的参数或者传递给函数的参数,参数是按照传递位置排列的
            如:

            ./01sh  123  abc  456
            123  abc  456  就是传递给脚本的参数

            $0      第0个参数,命令行的程序名称(./01sh)
            $1,$2,$3....${10}  表示第一个到第10个参数

            $#  表示命令行参数的个数(不包括脚本的名称)

            $@  表示所有的命令行参数(一个列表)
                $@ =======> "$1" "$2" "$3" ....
            $*  表示所有的命令行参数(一个数据)
                $* =======> "$1 $2 $3 ...."

            $?  表示前一个命令/函数/程序的退出码(返回值)

        3.环境变量
            shell解释器可以引用一些外部的变量(不需要定义,可以直接使用)
            如:

                HOME : 用户的家目录的路径
                ....
                需要重点记住的:
                LD_LIBRARY_PATH         动态库的搜索路径
                PATH                    命令或者可执行程序的搜索路径


            有没有发现一个问题?
            ls也是一个程序,cd也是一个程序,自己编译出来的a.out也是一个程序
            为什么我们在运行ls和cd的时候,不需要指定路径,系统就可以找到这个程序并且运行,而我们自己写的a.out就必须指定路径,否则找不到程序

        shell会自动到指定的路径下面去查找你输入的命令,如果找到了就执行,如果找不到就报错


"路径":PATH 
echo $PATH
 结果/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:
/bin:/usr/games:/usr/local/games:/usr/local/arm/5.4.0/usr/bin:
/snap/bin

​

            指定了系统要搜索的命令和可执行文件的目录列表
            PATH:dir1:dir2:.....

            我们也可以修改PATH的值,修改环境变量都是使用export
            格式:export 环境变量的名称=值
            如:

            export PATH=$PATH:/mnt/hgfs/CS2406F/2024-1-15Linux基础/code
            export WC=wangcai

            如果是在终端输入,只对当前终端有效,终端关闭之后,环境变量的值就失效了
            如果你想要环境变量永久有效,直接写入到系统的配置文件:
            1. ~/.bashrc  
                此配置只对当前用户有效
             每一次打开终端都会执行这个脚本文件,只需要把export那一句加入到文件的后面就可以了

            2. /etc/profile
                此配置只对所有用户有效,每一次开机都会执行这个脚本文件

            3. /etc/environment    <--------
                此配置只对所有用户有效

3.shell数组

shell数组和c语言中数组类似。同样不需要定义,可以直接使用,不能一次性赋值
    用法:

    数组名[下标]=value
        下标:0,1,2,3,4,5....n-1

    引用方式:
        ${数组名[下标]}
    引用数组中所有的元素:
        ${数组名[*]}
        ${数组名[@]}
    引用数组的第一个元素:
        ${数组名}

例如:

#!/bin/bash 
a[0]=1
a[1]=2
a[3]=abc
a[4]=456

echo ${a}
echo ${a[1]}
echo ${a[*]}
echo ${a[@]}


read var1 var2  < 1.txt
echo $var1 
echo $var2 

i=6
ret=`expr $i + 5 \* 3`
echo $ret

4.shell中的语句


    4.1说明性语句


        以#开头的行是说明性语句(注释),第一行除外 。

    4.2功能性语句


        功能性语句指的是一般任意的shell命令(如:ls echo cd date ...),自己写的程序
        上面两种可以直接运行,也可以使用反撇号获取结果

        shell内部的命令(read,expr,test....)
            read:在shell中表示从终端获取输入,保存到指定的变量
            如:
            read var1 var2
            从终端获取两个变量,第一个保存在var1中,第二个保存在var2中

            输入----->键盘(标准输入)
            输出----->终端/控制台(标准输出)
            输入和输出可以重定向到指定的位置


            4.2.1.输入重定向 


                命令的输入请求通常是向标准输入设备(键盘)提交请求
                我们也可以很方便的把输入重定向到一个文件,这种情况叫做输入重定向
                方法:
                    在该命令后面添加 < filename 
                    该命令的所有输入都来自于filename指定的文件

            4.2.2.输出重定向 


                命令(程序)的输出通常是提交到标准输出文件(终端/控制台)
                我们也可以很方便的把输出重定向到一个文件,这种情况叫做输出重定向
                方法:
                    在命令的后面添加 > filename
                    or 
                    在命令的后面添加 >> filename

                    >:会清空原先1.txt的内容,然后把命令的输出内容写入到1.txt文件
                    >>:追加输出,不会清空原先1.txt的内容,把命令的输出内容写入到1.txt文件的后面


            4.2.3.命令中的管道用法


                |
                用法:
                    命令1 | 命令2
                    命令1的输出内容作为命令2的输入
                如:

                    grep -nar main   查找当前目录中所有文件有main的行
                    grep -nar int   查找当前目录中所有文件有int的行
                    grep -nar main | grep int

                如:

            awk -F: '{print $1}' /etc/passwd

            #在所有用户中查找名字叫做china的用户的UID
             awk -F: '{print $1 $3}' /etc/passwd | grep china

                    -F:指定列的分隔符
                    $1:是分隔符分割之后的第一个字段(列)
                    /etc/passwd  你要处理的文件名
                    '{print $1}'  你要执行的动作


            expr:执行算术运算符命令

                expr主要用来进行简单的整数运算
                    +  - * / %
                如:
                    expr 5 + 3  (运算符两边,前后至少一个空格)
                    计算5+3的结果输出到标准输出
                    expr 5 - 3
                    expr 5 \* 3   *在shell中是一个通配符
                    expr 5 / 3
                    expr 5 % 3

                也可以把计算之后的结果赋值给指定的变量
                ret=`expr 5 + 3`
                i=6
                ret=`expr $i + 5 \* 3`

            test:测试语句

                test语句可以测试三种对象字符串  整数  文件 


                a.字符串测试   
                    测试两边的字符串内容是否完全相同
                        =的两边至少要有一个空格
                        如:
                            test "abc" = "abc"
                            echo $?     获取上一次命令的结果

                        结果:
                            相等结果为0
                            不相等结果为1

                        可以比较两个变量是否相同
                            str1=abc
                            str2=abc
                            test $str1 = $str2
                            echo $?

                        如果比较的时候,有一个字符串为空,就会出现语法错误
                            str1=abc
                            str2=
                            test $str1 = $str2 
                            echo $?

                            小技巧:
                            str1=abc
                            str2=
                            test ${str1}a = ${str2}a 
                            echo $?

                    !=  测试两个字符串的内容是否不相同
                        不相同返回0,相同返回1
                        test "abc" != "abc"
                        echo $?

                    -z   zero测试字符串是否为空
                        为空就返回0
                        test -z ${str2}

                    符合你描述的条件,返回0,不符合你描述的条件,就返回1
                b.整数测试    
                    #-eq    equal  测试两个整数是否相等,相等返回0
                    test 3 -eq 4
                    echo -eq:$?    #1

                    var1=123
                    var2=123
                    test $var1 -eq $var2 
                    echo -eq:$?    #0

                    #-ne  not equal  测试两个整数是否不相等,不相等返回0
                    test 3 -ne 4
                    echo -ne:$?    #0
                    test $var1 -ne $var2 
                    echo -ne:$?    #1

                    #-gt   greate than  测试一个整数是否大于另一个整数
                    test 3 -gt 4
                    echo -gt:$?    #1

                    var1=123
                    var2=12
                    test $var1 -gt $var2 
                    echo -gt:$?    #0

                    #-ge    greate and equal     测试一个整数是否大于等于另一个整数
                    test 3 -ge 4
                    echo -ge:$?    #1

                    var1=123
                    var2=123
                    test $var1 -ge $var2 
                    echo -ge:$?    #0


                    #-lt   little than  测试一个整数是否小于另一个整数
                    test 3 -lt 4
                    echo -lt:$?    #0

                    var1=123
                    var2=12
                    test $var1 -lt $var2 
                    echo -lt:$?    #1

                    #-le    little and equal     测试一个整数是否小于等于另一个整数
                    test 3 -le 4
                    echo -le:$?    #0

                    var1=123
                    var2=12
                    test $var1 -le $var2 
                    echo -le:$?    #1
                c.文件测试   
                    -d  filename 测试filename是否为一个目录文件(directory)
                    -f  filename 测试filename是否为一个普通文件
                    -L  filename 测试filename是否为一个链接文件
                    -p  filename 测试filename是否为一个管道文件
                    -s  filename 测试filename是否为一个socket文件
                    -c  filename 测试filename是否为一个字符设备文件
                    -b  filename 测试filename是否为一个块设备文件

                    test -d $1
                    echo $?


                    -r  filename    测试filename是否可读
                    -w  filename    测试filename是否可写
                    -x  filename    测试filename是否可执行
                    test -r filename
                    echo $?

                    test file1 -nt  file2     newer than 
                    测试file1是否修改时间在file2的后面

                    
                    test file1 -ot  file2     old than 
                    测试file1是否修改时间在file2的前面

                 最后test命令可以使用[]来缩写
                test Expression  <=========> [  Expression  ]
                如:
                [ $str1 = $str2 ]
                echo $?
                [ 和 ] 两边都必须有空格

            test的复合表达式
                相当于C语言的逻辑表达式(&& || )
                组合了两个或者两个以上的表达式叫做复合表达式
                使用方式:
                    可以使用test内置的操作符来创建复合表达式
                    test Expression1  "操作符"  Expression2
                    操作符:
                        -a     and   并且
                            全部满足才返回0
                        -o     or    或者
                            任意一个满足就返回0
                如:
                    测试..是否为目录的同时,测试位置变量$1和$2是否相等
                    test -d ".." -a $1 -eq $2
                    echo $?
                    ===========>
                    [ -d ".." -a $1 -eq $2 ]
                    echo $?

    4.3结构性语句(分支语句/循环语句)


        a.分支语句    


            相当于C语言中的if语句
            语法:
                if  command; then
                语句列表
                fi    #表示if语句结束
                -----------------------
                if  command; then
                语句列表1
                else 
                语句列表2
                fi    #表示if语句结束

            如:
                read var1
                if [ `expr $var1 % 2` -eq 0 ] 
                then
                echo 偶数!
                else
                echo 奇数!
                fi

例如:

#!/bin/bash 

read var1
if [ `expr $var1 % 2` -eq 0 ] 
then
echo 偶数!
else
echo 奇数!
fi
echo byebye


        b.多路分支语句(switch)


            语法:
                case 变量 in 
                模式1)
                ...
                ;;  #类似于C语言中的break,但是在shell中;;不能省略
                模式2)
                ...
                ;;
                模式n)
                ...
                ;;
                esac   #表示case语句结束
            
            case语句还有一个强大的功能在于可以使用"模式/规则"进行匹配而不是固定的字符串来匹配
            一个模式是由一串正常的字符串和特殊的通配符组成的字符串(可以是正则表达式)
                *   在shell中表示任意多个任意字符(可以是0个)
                ?  在shell中表示任意一个字符

例如:

read var2
case $var2 in 
a | b )
echo "input is a or b"
;;  #类似于C语言中的break,但是在shell中;;不能省略
c )
echo "input is c"
;;
d )
echo "input is d"
;;
[0-9])  #正则表达式
echo "input is digtal"
;;
*xx)  #通配符,表示任何以xx结尾的东西
echo "input is xxx"
;;
x?x)  #通配符
echo "input is yyyy"
;;

        c.循环语句   


            for循环   


            语法:
                for 变量名 in 单词表(列表)
                do 
                    循环体语句
                done
                
                单词表:以空格隔开的列表
                如:
                    ls的输出结果
                    a b c d e f g h 
                    shell中的数字
                    ....
                for循环的循环次数就是"单词表"中的单词的个数,并且每一次执行的时候,变量的值就是取单词表中的一个单词

                for var in a b c d e f g 
                do 
                    echo $var 
                    echo -------
                done 


                for var in `ls`
                do 
                    echo $var 
                    echo -------
                done 


                for也可以写成C语言的风格
                如:计算1~100的和

                sum=0
                for((i=0;i<=100;i++))   #C语言风格的for循环
                do 
                    sum=`expr $sum + $i`
                done 
                echo sum=$sum

            while循环


                语法:
                while 命令或者表达式
                do 
                    循环体语句 
                done 
                
                命令或者表达式经常是test取测试一个条件

                sum=0
                i=0
                while [ $i -le 100 ]
                do
                    sum=`expr $sum + $i`
                    i=`expr $i + 1`
                done
                echo sum=$sum


                sum=0
                i=0
                while((i<=100))
                do
                    sum=`expr $sum + $i`
                    i=`expr $i + 1`
                done
                echo sum=$sum
            until循环


                until   条件(命令/表达式)
                do 
                    循环体语句
                done 

                until和while语句的功能类似,不同的是,while只有当测试条件满足的时候,进入循环
                而until只有当测试条件不满足的时候,才进入循环,条件满足则退出循环,这一点刚好和while相反

                sum=0
                i=0
                until [ $i -gt 100 ]
                do
                    sum=`expr $sum + $i`
                    i=`expr $i + 1`
                done
                echo until_sum=$sum

                sum=0
                i=0
                until ((i>100))
                do
                    sum=`expr $sum + $i`
                    i=`expr $i + 1`
                done
                echo until2_sum=$sum

        d.break和continue 


            break n 
                跳出第n层循环(c语言中只能跳出当前循环)
            continue n 
                转到第n层循环语句开始执行下一次循环
                数字n表示,第几层循环
                break和continue后面也可以不加n,不加n表示的含义和C语言一样

5.shell中的函数 

5.1自定义函数的语法:


    function_name()
    {
        函数内部的命令列表
    }

    function_name:你自定义的函数的函数名,名字的取法和C语言类似(标识符)
    函数不要写参数,如果有参数就是使用"位置变量"

    函数定义之后不会自动执行,需要调用才会执行
    
    函数的调用语法:
        function_name  arg1 arg2 arg3 ....
        在函数的内部
            arg1 ------> $1
            arg2 ------> $2
            ....

   5.2 函数的返回值的获取,通常有两种方式:


    5.2.1.通过反撇号获取命令/函数的执行结果


        ret=`function_name arg1 arg2`
        反撇号是获取函数function_name执行时输出到标准输出的内容
        把原本输出到终端的所有的输出都赋值给变量ret

            sum()
            {
                s=`expr $1 + $2`
                echo $s
            }

            echo start
            ret=`sum 123 456`
            echo stop
            echo $ret

    5.2.2.使用位置变量$?


        $?表示的是上一条命令或者程序的退出码(函数的返回值)

            sum2 123 132
            结果是sum2最后一个命令或者表达式的值
            (在函数里面使用return返回你要返回的值)数字不能超过255

            sum2()
            {
                s=`expr $1 + $2`
                echo $s
                return $s
            }

            echo start
            sum2 123 132
            echo $? 
            echo stop

你可能感兴趣的:(linux,运维,服务器)