• Linux 下Shell的学习


    1.Shell学习

    1.什么是Shell
        shell是一个命令解析器,在操作系统的最外层,负责和用户对话,将用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果。
    2.什么是shell脚本
        当命令捉着语句不在命令行执行,而是通过一个程序文件执行的时候,改程序就是shell程序。
    3.需要注意的是ishell是包含命令,变量,流行和控制语句的脚本
    4.Shell脚本擅长处理纯文本类型的数据,
        Rsync Nfs Crond Ssh key 基础命令 Apache Mysql Php Nginx Lvx+keepalive + Iptables +Cacti/流量监控
    5.Shell脚本语言种类
        UNINX主要包括2大类:
            Bourne shell(sh,ksh,bash)  ->bash主流
            C shell(csh, tcsh)
        Linux的默认是Bash      -->标准的
        echo $SHELL            -->/bin/bash
            也可以通过cat /etc/passwd 查看一个用户对应的shell

    6.Shell与PHP,Perl,Pph语言的差别:
        Shell的优势在于快速的处理操作系统底层业务(大量的命令作支撑)
             一键安装,报警脚本,常规的业务,shell更简单
        Python:开发运维工具,WEB的管理界面,自动化等有优势
    7.常见的Linux脚本语言解析
        #!/bin/sh
        #!/bin/bash
        #!/bin/awk
        #!/bin/perl
        #!/usr/bin/env python

    2. Shell脚本的建立

    0.shell脚本规范
        1.#!/bin/sh 开头
        2.添加注释
        3.开头添加版本信息
        4.每次dos2unix格式化脚本  -->cat -v *.sh  可以查看
    1.shell脚本(bash shell程序)中编写
        脚本开头,指定哪个解析器来执行脚本的内容
        默认是/bin/sh,且必须是第一行
        如果环境没有,则必须在使用的时候指定解析器  sh h.sh 或 python h.py
            #!/bin/bash            -->必须是第一行,默认bash,如果环境没有,则必须在是用的时候指定解析器
                ==> #!/bin/sh      -->必须是第一行
                    ll /bin/sh     -->/bin/sh 是bash的链接文件,实为同一文件
    2.脚本的执行
        1.原理:
            当shell脚本非交互式运行的时候,会开始寻找环境变量ENV,找到指定的(.bashrc)文件,然后从该环境变量中执行脚本内容
        2.shell脚本常用的方式
            1.bash *.sh     |  sh *.sh
            2./bin/sh *.sh  |  ./*.sh(当前路径下)
            3.source *.sh   |  . *.sh(用点读入或者加载指定的脚本)
                -->source的作用是传递变量值到当前shell
                -->我们写的*.sh本事就是一个shell,但是在脚本shell里面的结果,不会传递给当前shell,所以使用将脚本shell里面的变量定义传递给我们看到的shell去呈现
                   所以使用点号可以将子脚本的结果作为输入传递到我们看到的shell里面
                   实际例子: vim /etc/init.d/nfs  -->里面调用函数库的时候就是使用点调用的
                               在一个脚本里面加载/调用另一个脚本里面的变量的时候,必须用点或者source

    3.Shell变量的基础及深入

    1.全局变量
        环境变量(全局变量):定义shell的运行环境,可以再创建他们的shell以及派生出来的任意子进程shell中使用
            例如:用户名,命令路径等,全局使用,每次用户登录均会初始化
            修改全局变量:  用户家目录下 ~/.bash_profile
                            /etc/profile
                            /etc/profile.d/
                            /etc/bashrc
            全局变量生效:source /etc/bashrc  
                            ==>  . /etc/bashrc
            全局变量查看:set
                            set可以像命令行一样设置传参
                            set -- "I am"  a student  -->3个参数
                            env
            取消全局变量:unset USER

            自定义全局变量:
                1.在修改全局变量的文件内使用export命令:
                    vi /etc/profile
                        export ftl ="Come on Ftl,Ha";      -->第一种方法
                        ftl = "Second Method " export ftl  -->第二种方法
                    source vi /etc/profile
                    echo $ftl

    局部变量:只能在创建他们的shell脚本中使用,用户创建,专用shell变量
        $a = ${a}

    2.导出变量名:
        export: 设置或显示环境变量
            在shell中执行程序时,shell会提供一组环境变量。
            export可新增,修改或删除环境变量,供后续执行的程序使用。
            export的效力仅及于该次登录操作。
            export 变量名=value
        其他:
            变量名=value; export 变量名
            declare -x 变量名=value

    3.单引号,双引号,不加引号的区别:
        一般情况下:
            单引号:输入即输出
            双引号:解析变量名,不扩展正则
            不加引号:连续字符串,与双引号无差异,如果字符串含有空格,则不能完整输出
        特殊情况下:
            awk: 单引号会解析变量,双引号则不能
        建议:
            1.直接定义:       ftl = 22
            2.有空格,双引号: ftl = "Come on boy"
            3.输入即输出,单引号
            4.变量名大写字母
            5.引用时${FTL}或者“$(FTL)”
            6.脚本中的局部变量:以local声明,只在本函数内有效
              脚本中的全局变量:大写
            7.变量学习: /etc/init.d/functions
    4.把命令定义为变量
        echo `date +%F`    -->反引号
        echo $(date +%F)  
        tar czvf hhh_${hhh}_ftl.tar.gz   -->容易引起误会的加大括号 :${变量名}
        推荐:平时就使用: 字符串变量用双引号括起来 “$A”或 ${A}
    5.shell的特殊变量
        1.位置变量
            $0: 获取当前脚本的名称,包括路径(前台是加入了脚本绝对路径:sh /home/omd/hhh.sh)
            $n: 获取当前的脚本的第n个参数,n=1..9,大于9,则需要大括号${10}
            $*: 获取当前shell的所有参数,将所有的命令行参数视为单个字符串,相当于“$1$2$3”
            $#: 当前shell命令行中参数的总个数
            $@: 这个程序的所有参数,作为一个i整体传递、
            basename $0: 只输出脚本名称
            dirname  $0: 输出路径的名称

        2.进程状态变量:
            $$: 获取当前shell的进程号
            $?: 判断上一个命令是否成功
                0:   成功
                2:   权限拒绝
                127: 命令无效
                >128:强制结束
            $_: 在此之前执行的命令或脚本的最后一个参数
            $@: 这个程序的所有参数

               
        3.答疑$#和$@的区别:
            $*: 将所有的参数当做一个参数进行传递,"$1$2$3"
            $@: 将每个参数视为单独的字符串,等同于"$1", "$2", "$3"  3个参数

                set -- "I am"  a student          -->临时定义了3个参数,set可以像命令行一样设置传参
                echo $#                           -->输出3
                for i in $*; do echo $i; done;    -->"$*"由于未加引号,所以会解析"I am"为2个字符
                for i in $@; do echo $i; done;    -->"$@"由于未加引号,所以会解析"I am"为2个字符
                for i in ; do echo $i; done;      -->什么都不加,相当于引用了加引号的“$@”,输出 I am   a student
                for i in "$@"; do echo $i; done;  -->输出 I am   a student
                for i in "$*"; do echo $i; done;  -->输出一整行"I am a student"

        4.Bash内部命令和shift
            echo:  变量名输出到标准设备
            eval args:  读入args参数,并将他们组合成一个新的命令,然后执行
            exec 参数:  当shell执行到exec的时候,不会去创建新的子进程,而是去执行指定的命令;
                          指定的命令执行完后,该进程(最初的shell)终止。
                        所以shell程序的exec后面的语句不再被执行
            export 变量名=value,把他的变量带入子shell,从而让子进程继承父进程中的环境变量
            read:  标准读入,传递给指定变量
            wait:  等待
            sleep: 休眠
            exit:  0成功退出  1异常退出
            shift: 重新命名所有位置的参数变量,即$2变成$1,直到$#为0
            .(点): ?
            readonly: 只读变量,显示所有的只读变

        5.Shell变量的子串应用技术
            常用操作:初步测试,对原文件不生效
                hello="Hello World"
                ${#String}: 统计字符数量  echo ${#hello}" -->11 | echo ${hello} |wc -m
                ${String:position:length}:
                    echo ${hello:2}   -->删除前2个字符,也即是从第三个输出到最后 -->llo world
                    echo ${hello:2:2} -->删除前2个字符,取出后面的2个字符 -->ll
                ${String#substring}   -->从变量$String开头,开始删除最短匹配字符$substring子串
                ${String##substring}  -->从变量$String开头,开始删除最长匹配字符$substring子串
                ${String%substring}   -->从变量$String结尾,开始删除最短匹配字符$substring子串
                ${String%%substring}  -->从变量$String结尾,开始删除最长匹配字符$substring子串
                ${String/#substring/replace} -->如果$string前缀匹配了$substring,就用replace代替
                ${String/%substring/replace} -->如果$string后缀匹配了$substring,就用replace代替
            总结一下:
                # :从前匹配
                % :从后匹配
                ::删除字符

        6.其他变量替换;
            ${value:-word}: 如果value已定义,则显示原来的默认值         -->判断变量未定义,可以解决变量未定义问题
                            如果value未定义,则显示值为word
                                result=${test:-UNSET}      -->如果test有值,则赋值给result
                                                           -->如果test为空,则设置-UNSET给result
                               
            ${value:=word}: 如果value已定义,则显示原来的默认值
                            如果value未定义,则设置默认值为word
                                result=${test:=UNSET}     -->如果test有值,则赋值给result
                                                          -->如果test为空,则设置-UNSET给test和result

            ${value:? "not default"}:用于捕捉变量未定义而导致的错误,并退出程序
                                result=${test:?"sorry"}  -->如果test有值,则赋值给result
                                                          -->如果test为空,则显示-bash:test sorry,并退出

            ${value:+word}:测试变量是否存在,如果已经定义,则返回word
                                result=${test:+hello}     -->如果test有值,则返回hello
                                                          -->如果test为空,则返回null

            ${value-word}:去掉冒号  httpd=${HTTPD-/usr/local/httpd}    -->/etc/httpd
                          如果变量未存在,则用后面的替代

            说明:    每个运算符内的冒号都是可选的  -->用于判断测试变量是否存在
                        带帽号:存在且非null
                        去冒号:存在
                    /etc/init.d/httpd
                    /etc/init.d/crond
                    对路径进行操作的时候,最好先进行路径判断是否为空,然后后进入目标路径删除
                        path=/home/omd
                        cd $path
                        find ${path:=/home/omd/} -name "*.txt"|xargs rm -f
                            #rm -rf ${path:=/tmp} 
                                        --->注意增加${path:=/home/omd}和omd加反斜线,防止omd目录被干掉

    shell开发规范

    1.指定脚本解析器
    #!/bin/sh
    2.开头添加版本版权等信息
    #Date     2017-0905-21:00
    #Author   Lvfengtao
    #Mail     ws415659
    #Function This script is for MysqlBakcup
    #Version  V1.1.1
        可以配置Vim的品配置文件 ~/.vimrc添加2的内容
    3.脚本尽量少用中文注释
    4.脚本以*.sh结尾
    5.代码书写优秀习惯
        1.成对的内容一起输出
            {} [] '' "" ``
        2.[]括号的2端必须有空格,书写时[  ],退格在书写[ fsfs ]
        3.if语句格式一次成型
            if 条件内容
                then
                    内容
            fi
        4.for 循环一次成型
            for n in list
                do
                    内容
                done;
    6.通过缩写让代码易读


    【更多参考】

    Linux 下Shell的学习2

    Linux 下Shell的学习3-demo

    Linux 下shell中exec解析

  • 相关阅读:
    Amazon Route 53
    监控应用程序负载均衡器ALB
    DynamoDB 流
    DynamoDB 中的限制
    Amazon SNS 消息属性
    关于基于 SAML 2.0 的联合身份验证
    Amazon EBS 性能提示
    Laravel5.1注册中间件的三种场景
    编译LNMP环境
    傻瓜式搭建LAMP环境
  • 原文地址:https://www.cnblogs.com/ftl1012/p/shell.html
Copyright © 2020-2023  润新知