shell 基础

1.什么是shell?

1.一个编程的语言
2.可以执行的文件
3.文件内容 linux 命令组成的

2.shell语法入门

入门

    1.文件 xxx.sh 文件 
    2.第一行 #!/bin/bash

1.编写脚本

        [root@liunxandshell shell]# vim hello.sh
        #!/bin/bash
        echo "world count"

2.得有执行权限【不一定】

1.不给文件权限 执行

        [root@liunxandshell shell]# sh ./hello.sh 
        world count
        [root@liunxandshell shell]# cat ./hello.sh 
        #!/bin/bash
        echo "world count"

2.给文件 执行权限【推荐】

        [root@liunxandshell shell]# chmod 744 ./hello.sh 

        [root@liunxandshell shell]# sh ./hello.sh 
        world count

        [root@liunxandshell shell]# ./hello.sh 
        world count

补充:

1.给权限

            赋予权限的第二种方式
            [root@liunxandshell shell]# chmod u+x ./hello.sh 
            [root@liunxandshell shell]# ./hello.sh 
            world count

2.执行路径

            绝对路径执行
            [root@liunxandshell shell]# /root/shell/hello.sh 
            world count
            [root@liunxandshell shell]# sh /root/shell/hello.sh 
            world count

3.debug

            1.sh -x
                【加号是debug过程中】
                [root@liunxandshell shell]# sh -x ./hello.sh 
                + echo 'world count'
                world count
            2.文件内
                【在第一行加上 -x】
                #!/bin/bash -x
                echo "world count"

                [root@liunxandshell shell]# ./hello.sh 
                + echo 'world count'
                world count

思考:sh 可以grep吗? 【意义不大,还得研究】

            [root@liunxandshell shell]# cat variable.sh 
            name="xianyu"
            dt1="date"
            dt2=`date`
            echo ${name}
            echo ${dt1}
            echo ${dt2}

            [root@liunxandshell shell]# ./variable.sh | grep date
            date
            [root@liunxandshell shell]# sh -x ./variable.sh | grep date
            + name=xianyu
            + dt1=date
            ++ date
            + dt2='2022年 04月 14日 星期四 10:22:08 CST'
            + echo xianyu
            + echo date
            + echo 2022年 04月 14日 星期四 10:22:08 CST
            date

            [root@liunxandshell shell]# sh -x ./variable.sh | grep xianyu
            + name=xianyu
            + dt1=date
            ++ date
            + dt2='2022年 04月 14日 星期四 10:39:59 CST'
            + echo xianyu
            + echo date_1
            + echo 2022年 04月 14日 星期四 10:39:59 CST
            xianyu

2.定义变量

    案例
    [root@liunxandshell shell]# cat variable.sh 
    name="xianyu"
    dt1="date"
    dt2=`date`
    echo ${name}
    echo ${dt1}
    echo ${dt2}
    [root@liunxandshell shell]# ./variable.sh 
    xianyu
    date
    2022年 04月 14日 星期四 10:19:06 CST

1.定义变量的方式:

        key=value
        注意:
            1.= 前后不能有空格
            2.变量名一般都是大写的

2.变量的种类

        shell中变量的数据类型 => string
        1.静态
            k="v"   k='v' k=v
        2.动态
            k=`v` :v是变量 v系统自带的命令
        3.引用
        1.$k 
        2.${k}【建议使用这个,可以在后面拼接字符串】

    任务调度:
        shell => 
            时间点  T+1 、 h+1  20min
                20220414 =》 20220413
                    20220414 0:05
                        1.yarn资源【这块有实时监控yarn资源的项目】
                        2.看你几点上班,上班之前跑出来
                    公司在意有没有一个真正解决问题的东西
        crontab 命令 =》 定时调度
        开源框架:
            dophinscheduler【最好用,恢复数据、重跑数据】[https://dolphinscheduler.apache.org/zh-cn/](https://dolphinscheduler.apache.org/zh-cn/)
            xxl【好用 shell脚本填进去】
            airflow【费劲但好用】
            runduck
            自己开发
    
            azkaban => 血缘关系 【数仓任务】 => Apache Atlas元数据血缘关系【比较鸡肋,不太好用】
                done => mysql => web
    java
    maven
    quickstart

3.参数传递

    1.$n 
        $1 $2 ...

案例

    [root@liunxandshell ~]# cat ./par.sh 
    echo "脚本文件名:$0"
    echo "第一个参数:$1"
    echo "第二个参数:$2"
    echo "参数个数:$#"
    echo "传递的参数作为一个字符串:$*"
    echo "传递的参数作为一个字符串:$@"
    echo "脚本运行时的pid:$$"

最后一行的意义:

    # 假如是一个实时程序,要通过pid来查
    # ps -ef | grep sparkxxx => pid kill可能会kill错

    [root@liunxandshell ~]# ./par.sh "hello word" word2
    脚本文件名:./par.sh
    第一个参数:hello word
    第二个参数:word2
    参数个数:2
    传递的参数作为一个字符串:hello word word2
    传递的参数作为一个字符串:hello word word2
    脚本运行时的pid:6721

补充:

        1.传递参数 “空格” 作为符号分割
        2.参数本身带有空格 要加双引号

4.数组

语法格式:

        arr=(v1 v2 ... vn)
        1.数组用()表示
        2.元素用 空格 分割

案例

        [root@liunxandshell ~]# cat arr.sh 
        arr=(xy lxy dxy haha)
        echo "所有元素:${arr[@]}"
        echo "第一个元素:${arr[0]}"
        echo "元素个数:${#arr[@]}"
        [root@liunxandshell ~]# ./arr.sh 
        所有元素:xy lxy dxy haha
        第一个元素:xy
        元素个数:4

5.流程控制

    条件表达式 不能用 < >

1.分支if else

语法格式:

        if condition;then
            业务代码
        else
            业务代码
        fi

        condition => 条件判断语法
            [ condition ]
            注意:前后都是有空格的
            结果:
                非空 true
                空 false
            [ hadoop ]
            $? => 获取上一个程序运行的结果
                1.成功 0
                2.失败 非0的数

案例

                [root@liunxandshell shell]# [ hadoop ]
                [root@liunxandshell shell]# echo $?
                0

2.分支if elif else

语法结构

            if condition;then
                业务代码
            elseif condition;then
            else
                业务代码
            fi

案例

            score=$1
            if [ ${score} -gt 90 ];then
            echo "优秀"
            elif [ ${score} -ge 60 ];then
            echo "良"
            else
            echo "不及格"
            fi

3.条件表达式

1.数值判断

            = 等于
            == 等于
            -lt 小于
            -eq 等于
            -ge 大于等于
            -le 小于等于
            -gt 大于
            -ne 不等于

        案例
            name1="xy"
            name2="lxy"
            if [ ${name1} == ${name2} ];then
                    echo "等于"
            else
                    echo "不等于"
            fi
            
            [root@liunxandshell shell]# ./if.sh 
            不等于

2.权限判断

        -r
        -w 
        -x 

3.文件判断

        -f 
        -e 
        -d 

4.循环

        while for 能用 < > 不能用 -gt

1.foreach

        foreach:
            for el in item1 item2 ...itemn 【这可以 for el in arr】
            do 
                业务代码
            done
            案例
            for x in 1 2 3 4
            do
                echo "${x}"
            done

2.for i

            for ((i=0;i<size;i++))
            do 
                业务代码
            done
            案例
            for ((i=0;i<5;i++))
            do
                echo "v is ${i}"
            done

3.while:

            while condition
            do
            业务代码
            done

            案例【<= 不能换 -le】
            [root@liunxandshell shell]# cat ./while.sh 
            i=1
            while(($i<=5))
            do
                echo "v is ${i}"
                let i++
            done

流程控制总结:

    条件表达式 不能用 < >
    while for 能用 < > 不能用 -gt
    [https://www.cnblogs.com/qlqwjy/p/8684630.html](https://www.cnblogs.com/qlqwjy/p/8684630.html)
    区别: [] 和 ()
        [] => 条件判断 
        () => 用于 数值运算

    [root@liunxandshell shell]# echo $[1+2]
    3
    [root@liunxandshell shell]# echo $((1+2))
    3

案例:监控 服务器
    ip hostname
    linux01 linux02 linux03

    df 磁盘
    free 内存

    不要指定多个参数,最好一个字符串替换

    str="linux01,linux02,linux03"
    替换
    arr=(${str//,/ })
    for linux in ${arr[@]}
    do
        echo "${linux}"
    done

    [root@liunxandshell shell]# ./split.sh 
    linux01
    linux02
    linux03


    srt.split(",") 【好好掌握】
    shell =>
        IFS变量 => 字符串分割的效果

补充: linux 文本分析的 命令

    awk => 取出文本内容
    sed => 文本替换

1.awk【多用某个框架的启动和停止脚本】

        数据
            [root@liunxandshell shell]# cat 1.log 
            a b c
            1 2 3

1.获取列

            [root@liunxandshell shell]# cat 1.log | awk '{print $1}'
            a
            1
            [root@liunxandshell shell]# cat 1.log | awk '{print $1,$2}'
            a b
            1 2

2.获取行

            [root@liunxandshell shell]# cat 1.log | awk 'NR==1{print}'
            a b c
            [root@liunxandshell shell]# cat 1.log | awk 'NR==2{print}'
            1 2 3
            [root@liunxandshell shell]# cat 1.log | awk 'NR>1{print}'
            1 2 3
            [root@liunxandshell shell]# cat 1.log | awk 'NR>=1{print}'
            a b c
            1 2 3

2.sed

        文本替换
        数据
            [root@liunxandshell shell]# cat 2.log 
            a a b
            1 a 3

1.a 替换成 dd

            [root@liunxandshell shell]# sed -i 's/a/dd/' 2.log #每行第一次遇到a替换成dd
            [root@liunxandshell shell]# cat 2.log 
            dd a b
            1 dd 3

2.全局替换

            sed -i 's/a/dd/g' 2.log

            [root@liunxandshell shell]# sed -i 's/a/dd/g' 2.log
            [root@liunxandshell shell]# cat 2.log 
            dd dd b
            1 dd 3
            坑:
            【's/a/dd/g'不一定用反斜杠,也可以用# sed -i 's#dd#b#g' 2.log】
                替换文件路径
                    /path/a

                    p1="/path/a" => 换成
                    p1="/path1/a1"
                    看不懂
                    sed -i 's/\/path\/a/\/path1\/a1/g' 3.log
                    [root@liunxandshell shell]# sed -i 's/\/path\/a/\/path1\/a1/g' 3.log
                    [root@liunxandshell shell]# cat 3.log 
                    p1="/path1/a1"
                    舒适易读
                    sed -i 's#/path/a#/path1/a1#g' 3.log
                    [root@liunxandshell shell]# sed -i 's#/path/a#/path1/a1#g' 3.log
                    [root@liunxandshell shell]# cat 3.log 
                    p1="/path1/a1"
posted @ 2022-04-14 18:11  咸鱼QwQ  阅读(36)  评论(0)    收藏  举报