• Linux基础学习笔记6-SHELL编程


     

    编程基础

    程序:指令+数据
    程序编程风格:
        过程式:以指令为中心,数据服务于指令
        对象式:以数据为中心,指令服务于数据
    shell程序:提供了编程能力,解释执行
    编程基本概念:
        顺序执行;循环执行;选择执行
    shell编程:过程式、解释执行
        编程语言的基本结构
            各种系统命令的组合
            数据存储:变量、数组
            表达式:a+b
            语句:if
    

    shell脚本基础

    shell脚本:包含一些命令或声明,并符合一定格式的文本文件
    格式要求:首行shebang机制
        #! /bin/bash
        #! /usr/bin/python
        #! /usr/bin/perl
    shell脚本的用途有:
        自动化常用命令
        执行系统管理和故障排序
        创建简单的应用程序
        处理文本或文件
    

    创建shell脚本

    第一步:使用文本编辑器来创建文本文件
        第一行必须使用包括shell声明序列:#
            #!/bin/bash
            添加注释
            注释以#开头
        第二步:运行脚本
            给予执行权限,在命令行上指定脚本作为解释器程序的参数运行
            直接运行解释器,将脚本作为解释器程序的参数运行
    
    脚本规范:
    脚本代码开头约定
      1.第一行一般为调用使用的语言
      2.程序名,避免更改文件名为无法找到正确的文件
      3.版本号
      4.更改后的时间
      5.作者相关信息
      6.该程序的作用,及注意事项
      7.最后是各版本的更新及简要说明
    脚本的基本结构:
      #!SHEBANG
      CONFIGURATION_VARIABLES
      FUNCTION_DEFINITIONS
      MAIN_CODE
    
    shell脚本示例:

    脚本调试

    检测脚本中语法错误 
        bash -n /path/to/some_script
    调试执行
        bash -x /path/to/some_script

    变量

    变量:命名的内存空间
        数据存储方式:
        字符:
        数值:整型、浮点型
    变量:变量类型
        作用:1.数据存储格式
             2.参与的运算
             3.表示的数据范围
    
    强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。一般定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误。如java,c#
    弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用。如bash不支持浮点数,php
    变量命名规则:
      1.不能使用程序中的保留字:例如if,for
      2.只能使用数字、字母及下划线,且不能以数字开头
      3.见名知义
      4.统一命名规则:驼峰命名法

    bash中变量的变种

    根据变量的生效范围等标准划分下面变量类型:
      局部变量:生效范围为当前shell进程;对当前shell之外的其他shell进程,包括当前shell的子shell进程均无效
      环境(全局)变量:生效范围为当前shell进程及其子进程(利用export声明即为环境变量)
      本地变量:生效范围为当前shell进程中某代码片段,通常指函数
      位置变量:$1,$2,...来表示,用于让脚本在脚本代码中调用命令行传递给它的参数
      特殊变量:$?,$0(代表脚本名称),$*(代表所有参数),$@(代表所有参数),$#(代表参数数量),$$
    注意:#@与#*的区别在于#*会将所有位置参数当成一个整体
    echo $$:查看当前shell运行的系统编号
    pstree -p:查看当前系统运行的shell树状结构
    scp命令:可以跨网络将本机数据发送到另外一台机器上
    
    局部变量
    变量赋值:name='value'
    可以使用引用value:
      (1)可以是直接字串;name="root"
      (2)变量引用:name="$USER"
      (3)命令引用:name='COMMAND' name=$(COMMAND)
    变量引用:${name} $name
      "":弱引用,其中的变量引用会被替换为变量值
      '':强引用,其中的变量引用不会被替换为变量值,而保持源字符串
    显示已定义的所有变量:set
    删除变量:unset name
    
    环境变量
    变量声明、赋值
      export name=VALUE
      declare -x name=VALUE
    变量引用:$name,${name}
    显示所有环境变量:
      env
      printenv  
      export  
      declare -x
    删除变量 unset name
    
    bash内建的环境变量:PATH,SHELL,USER,UID,HOME,PWD,SHLVL,MAIL,HISTSIZE,- 等等。
      

    只读和位置变量

    只读变量:只能声明,但不能修改和删除
        声明只读变量:readonly name    
                            declare -r name
        查看只读变量:readonly -p
    位置变量:在脚本代码中调用通过命令行传递给脚本的参数
        $1,$2,...:对应第一,第二等参数,shift[n]换位置
        $0:命令本身
        $*:传递给脚本的所有参数。全部参数合为一个字符串
        $@:传递给脚本的所有参数,每个参数为独立字符串
        $#:传递给脚本的参数个数
                $@ $* 只在被双引号包起来的时候才会有差异
        set -- 清空所有位置变量  

    退出状态

    进程使用退出状态来报告成功或失败
        0代表成功,1-255代表失败
        $?变量保存最近的命令退出状态
    例如:
            print -c1 -W1 hostdown &> /dev/null
            echo $?
    退出状态码
    bash自定义退出状态码
    exit[n]:自定义退出状态码
    注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字;
    如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

     算术运算

    bash中的算术运算:help let
        +,-,*,/,%取模(取余),**(乘方)
        实现算术运算:
        (1)let var=算术表达式
        (2)var=$[算术表达式]
        (3)var=$((算术表达式))
        (4)var=$(expr arg1 arg2 ...)
        (5)declare -i var =数值
        (6)echo '算术表达式' | bc
    乘法符号在有些场景中需要转义,如*
    bash有内建的随机数生成器:$RANDOM(0-32767)
        echo $[$RANDOM%50]:0-49之间随机数
    
    赋值:+=,-=,==,/=,%=
    let var OPER value:let count+=3
    自增自减:let var +=1 ;let var++ ;let var -=1; let var--;

    逻辑运算

     

     条件测试

    判断某需求是否满足,需要由测试机制来实现
        专用的测试表达式需要由测试命令辅助完成测试过程
    评估布尔声明,以便用在条件性执行中
        若真,则返回0
        若假,则返回1
    测试命令:
        test EXPRESSION
        [EXPRESSION]
        [[EXPRESSION]](这种情况适用于带有正则表达式的情况)
    注意:EXPRESSION前后必须有空白字符
    
    条件性的执行操作符
    根据退出状态而定,命令可以有条件地运行
      && 代表条件性的AND THEN
      || 代表条件性的OR ELSE
    例如:
      grep -q no_such_user /etc/passwd || echo 'No such user'  
      输出:No such user
      ping -c1 -W2 station &> /dev/null > && echo "Station1 is up" > ||(echo 'Station1 is unreachable';exit1)
      输出:Station1 is up
    
    test命令(内部命令,查看帮助:help test)
      长格式的例子:
        test "$A" == "$B" && echo "Strings are equal"
        test "$A" -eq "$B" && echo "Integers are equal"
      简写格式的例子:
        ["$A" == "$B"] && echo "Strings are equal"
        ["$A" -eq "$B"] && echo "Integers are equal"
     
    bash的数值测试
    -v VAR:变量VAR是否设置
    数值测试:
      -gt  是否大于
      -ge  是否大于等于
      -eq  是否等于
      -ne  是否不等于
      -lt  是否小于
      -le  是否小于等于
    bash的字符串测试
      ==  是否等于
      >  ascii码是否大于ascii码
      <  是否小于
      !=  是否不等于
      =~  左侧字符串是否能够被右侧的PATTERN所匹配(此表达式一般用于[[]]中;扩展的正则表达式)
      -z  "STRING"  字符串是否为空,空为真,不空为假
      -n  "STRING"  字符串是否不空,不空为真,空为假
    注意:用于字符串比较时用到的操作数都应该使用引号

     bash的文件测试

    存在性测试
      -a FILE:同-e
      -e FILE:文件存在性测试,存在为真,否则为假
    存在性及类别测试
      -b FILE:是否存在且为设备文件
              

    示例:[-f /etc/issue] && echo true

       [-d /etc/] && echo true

    bash文件权限测试

    文件权限测试:
        -r FILE:是否存在且可读
        -w FILE:是否存在且可写
        -x FILE:是否存在且可执行
    文件特殊权限测试:
        -u FILE:是否存在且拥有suid权限
        -g FILE:是否存在且拥有sgid权限
        -k FILE:是否存在且拥有sticky权限
    

    bash的文件属性测试

    文件大小测试
        -s FILE:是否存在且非空
    文件是否打开:
        -t fd:fd文件描述是否在某终端已经打开
        -N FILE:文件自从上一次被读取之后是否被修改过
        -O FILE:当前有效用户是否为文件属主
        -G FILE:当前有效用户是否为文件属组
    双目测试:
      FILE1 -ef FILE2:FILE1是否是FILE2的硬链接
      FILE1 -nt FILE2:FILE1是否新于FILE2(mtime)
      FILE1 -ot FILE2:FILE1是否旧于FILE2  

    bash的组合测试条件

    第一种方式:
        COMMAND1 && COMMAND2
        COMMADN1 || COMMADN2
        !COMMAND
        如:[[ -r FILE ]] && [[ -w FILE ]]
    第二种方式:
        EXPRESSION1 -a EXPRESSION2
        EXPRESSION1 -o EXPRESSION2
        !EXPRESSION
        必须使用测试命令进行
    示例:[ -z "$HOSTNAME" -o "$HOSTNAME"=="localhost.localdomain"] && hostname www.ccsu.com [ -f /bin/cat -a -x /bin/cat] && cat /etc/fstab  

    使用read命令来接收输入

    使用read来把输入值分配给一个或多个shell变量    
        -p 指定要显示的提示
        -s 静默输入,一般用于密码
        -n N 指定输入的字符串长度
        -d '字符'输入结束符
        -t N TIMEOUT为N秒
        read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量
        read -p "Enter a filename:" FILE
    

    流程控制 

    过程式编程语言:
        顺序执行
        选择执行
        循环执行

    条件选择if语句

    if语句示例:
        read -p"please onput your age:" age
      [[ "$age" =~ [0-9]+$ ]] ||{echo your age is false;exit10;}
        if [ "$age" -gt 0 -a  "$age" -le 18];then
                echo "you are young"
        elif[ "$age" -gt 18-a  "$age" -le 50];then
                echo woek hard
        elif ["$age" -gt 50 -a  "$age" -le 80];then
                echo "very ok"
        else
                echo "you do not come from earth"
        fi

    条件判断:case语句

    case语句示例:
        read -p"Do you agree?tes or no:"anwser
        case $answer in
        [Yy]|([Yy][Ee][Ss])
                echo your answer is yes
                ;;
        [Nn]|[Nn][Oo])
                echo your answer is no
                ;;
        *)
                echo your answer is false
                ;;
        esac

    循环

    循环执行
        将某段代码重复运行多次
        重复运行多少次
            循环次数事先已知
            循环次数事先未知
        有进入条件和退出条件
    for;while;until

     for循环

     

    for循环示例1
        显示root下所有的txt格式文件:
        for name in `ls /root/*.txt`;do echo "$name";done 
    for循环示例2
      求1-100之间的奇数和
      sum=0;for number in `seq 1 2 100`;do let sum+=number;done;echo "sum is $sum"

    while循环

    while循环示例1
      求1-100之间的奇数和
      sum=0;i=1;while ["$i" -le 100];do let sum+=i;let i+=2;echo "sum is $sum" 

    until循环

    循环控制语句continue

    循环控制语句break

    for循环的特殊用法:

    for循环的特殊用法示例:
        求1-100之间的奇数和
        for((sum=0,i=1;i<100;i+=2));do let sum+=i;done;echo "sum is $sum"

    函数介绍

    函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程
    它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分
    函数和shell程序比较相似,区别在于:
        shell程序在子shell中运行
        而shell函数在当前shell中运行。因此在当前shell中,函数可以对shell中变量进行修改

    定义函数

    cat /etc/init.d/functions 查看系统自定义的函数

     函数使用

    函数返回值

    函数返回值示例:
    checkip(){
      [[ "$1" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]  && echo "This is a IP" || {echo "This is not IP" ;return 10;}
    }
    注意:返回值返回给了调用者  

    交互式环境下定义和使用函数

    在脚本中定义及使用函数

    定义一个ip检查函数
    checkip(){
      [[ "$1" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]  && echo "This is a IP" || echo "This is not IP"
    }
    调用函数
    checkip
    删除函数
    unset checkip 

    使用函数文件

    创建函数文件

     

    载入函数

    检查载入函数

    执行shell函数

    删除shell函数

    函数参数:

    函数变量

    局部变量示例

    函数递归示例

    函数递归示例

    fork炸弹

    数组

    数组赋值

    引用数组

    数组数据处理

    数组示例1

    数组示例2

    做一枚奔跑的老少年!
  • 相关阅读:
    [HTML5] document.hidden
    在vue页面中设置resize事件
    document之ES6解构
    vue中mixins的使用方法和注意点---mixins第二篇(异步请求的情况)
    vue中mixins的使用方法和注意点---mixins第一篇
    vue中路由重定向redirect
    如何理解dispatch( 'tagsView/delAllViews',null,{root:true} )里面的root:true
    vue计算属性computed中的get和set的使用
    splice(0)的奇妙用法
    4月5日学习日志
  • 原文地址:https://www.cnblogs.com/xiaoshayu520ly/p/10571115.html
Copyright © 2020-2023  润新知