• 高级BASH


    Bash介绍与入门

    1,简介

    Bash(GNU Bourne-Again Shell)是一个为GNU计划编写的Unix shell,它是许多Linux平台默认使用的shell

    shell是一个命令解释器,是结余操作系统内核与用户之间的一个绝缘层。

    2,为什么学Bash

    对于任何想适当精通一下系统管理知识的人来说,掌握shell脚步知识都是最基本的。

    3,初步练习

    (1)Hello World

     

    (2)使用脚步清除/var/log下的log文件

    查看/var/log下的log文件,并创建新的脚本

     

    代码:

     

    实验机有点差别,有权限,不给删除

     

     

    Bash的特殊字符(上)

    一、#符号

    1.#注释

    行首以#开头(除#!之外)的是注释。#!是用于指定当前脚本的解释器,我们这里为bash,且应该指明完整路径,所以为/bin/bash

    代码:

     

    结果:

     

    二、分号(;)

    1.命令分隔符

    使用分号(;)可以在同一行上写两个或两个以上的命令

    输入代码:

     

     

    执行脚本:

     

    2.终止case选项(双分号)

    使用双分号(;;)可以终止case选项

    输入代码

     

    执行脚本:

     

    上面脚本使用case语句,首先创建了一个变量初始化为b,然后使用case语句判断该变量的范围,并打印相关信息。

    三,点号(.)

    1.等价于source命令

    bash中的source命令用于当前bash环境下读取并执行FileName.sh中的命令

     

    四,引号

    1,双引号(“)

    “STRING”将阻止(解释)STRING中大部分特殊的字符。

    2,单引号(‘)

    ’STRING‘将会阻止STRING中所有特殊字符的解释,这是一种比使用“更强烈的形式。

    五,斜线和反斜线

    1,斜线(/)

    文件名路径分隔符。分隔文件名不同的部分

    (如/home/bozo/projects/Makefile)。也可以用来作为除法算数操作符

    2,反斜线()

    一种对单字符的引用机制。X将会“转义”字符X。这等价于“X",也等价于'X'。通常用来转义双引号(“)和单引号(’),这样双引号和单引号就不会被解释成特殊含义

    六,反引号(`)

    1,命令替换

    command结构可以将命令的输出赋值到一个变量中去。在后边的后置引用(backquotes)或后置标记(backticks)中也会讲解。

    反引号中的命令会优先执行,如:

     

    先创建了back目录,然后赋值test.sh到back目录

    七,冒号(:)

    1,空命令

    等价于“NOP”(no op,一个什么也不干的命令)。也可以被认为与shell的内建命令true作业相同。“:”命令是一个bash的内建命令,它的退出码(exit status)是(0)。

     

    等价于

     

    可以在if/then中作占位符

    2.变量扩展/子串

    在与>重定向操作符结合使用时,将会把一个文件清空,但是并不会修改这个文件的权限。如果之前这个文件并不存在,那么就创建这个文件。

     

    在与>>重定向操作符结合使用时,将不会对预先存在的目标文件(:>>target_file)产生任何影响。如果这个文件之前并不存在,那么就创建它。

    也可能用来作为注释行,但不推荐这么做。使用#来注释的话,将关闭剩余行的错误检查,所以可以在注释行中写任何东西。然而,使用的话将不会这样做。如:

     

    “:”还用来在/etc/passwd和¥PATH变量中做分隔符,如:

     

    八,问号(?)

    1,测试操作符

    在一个双括号结果中,?就是C语言的三元操作符,如:

    代码:

     

    运行测试:

     

    九,美元符号

    1,变量替换

    命令:

     

    测试运行:

     

    2,命令替换(同反引号)

     

     

    Bash中的特殊字符(下)

    一,小括号(())

    1,命令组

    在括号中的命令列表,将会作为一个子shell来运行

    在括号中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的。父进程,也就是脚本本身,将不能够读取在子进程中创建的变量,也就是在子shell中创建的变量。如:

     

    运行代码

     

    在圆括号中a变量,更像是一个局部变量

    2,初始化数组

    创建数组

     

    输入代码:

     

    运行结果

     

     

    二,大括号

    1,文件名扩展

    复制t.txt的内容到t.back中

     

    注意:大括号中,不允许有空白,除非这个空白被应用或转义。

    2,代码块

    代码块,又被称为内部组,这个结果事实上创建了一个匿名函数(一个没有名字的函数)。然而,与“标准”函数不同的是,在其中声明的变量,对于脚本其他部分的代码来说还是说可见的。

     

    三,中括号([])

    1,条件测试

    条件测试表达式在[ ]中。值得注意的是[是shell内建test命令的一部分,并不是/usr/bin/test中的外部命令的一个链接。下列练习中的-lt(less than)表示小于号

     

     

     

    双中括号中([[ ]])也用作条件测试(判断)

    2,数组元素

    在一个array结构的上下文中,中括号用来引用数组中每个元素的编号

     

     

     

    四,尖括号(<和>)

    1,重定向

    test.sh > filename重定向test.sh的输出到文件filename中。如果filename存在的话,那么将会被覆盖。

    test.sh &> filename重定向test.sh的stdout(标志输出)和stderr(标准错误)到filename中

    test.sh >&2重定向到test.sh的stdout到stderr中

    test.sh >> filename把test.sh的输出追加到文件filename中。如果filename不存在的话,将会被创建。

    五,竖线(| )

    管道

    分析前边命令的输出,并将输出作为后边命令的输入。这是一种产生命令链的好方法

     

     

     

    输出的内容均变为了大写字母

    六,破折号( - )

    1,选项,前缀

    在所有的命令内如果想使用选项参数的话,前边都要加上“-”

     

     

     

    2,用于重定向stdin或stdout

    下面的脚本用于备份最后24小时当前目录下所有修改的文件

     

    七,波浪号(~)

    1,目录

    ~表示home目录

     

    变量和参数

    一,变量替换

    1.概念

    变量的名字就是变量保存值得地方。引用变量的值就叫做变量替换。

    如果variable是一个变量的名字,那么$variable就是引用这变量的值,即这变量所包含的数据

    $variable事实上只是${variable}的简写形式。在某些上下文中$variable可能会引起错误,这时候你就需要用${variable}了。

    2.举例

     

    结果:

     

    二,变量赋值

    1,说明

    赋值操作前后都不能有空白

    因为 = 和 -eq 都可以用做条件测试操作,所以不要与这里的赋值操作相混淆

    注意:=既可以用做条件测试操作,也可以用于赋值操作,这需要视具体的上下文而定。bash中==也可作为条件判断。

     

    运行结果 

    三,变量不区分类型

    1,说明

    与大多数编译型语言不同,Bahs并不区分变量的“类型”。本质上Bash变量都是字符串。但是依赖于具体的上下文,Bahs也允许比较和整数操作。其中的关键因素就是,为变量赋的值是否只有数字

    2,举例:

     

    运行结果:

     

     

    四,特殊变量

    1,局部变量

    这种变量只有在代码块或函数中才可见。

    2,环境变量

    这种变量将影响用户接口和shell的行为

    在通常情况下,每个进程都有自己的"环境“,这个环境是由一组变量组成的,这些变量中存在进程可能需要引用的信息。在这种情况下,shell与一个一般的进程没什么区别。

    3,位置参数

    从命令行传递到脚本的参数:$0,$1,$2,$3...

    $0就是脚本文件自身的名字,$1是第一个参数,$2是第二个参数,$3是第三个参数,然后是第四个。$9之后的位置参数就必须用大括号括起来了,比如,${10},${11},${12}。

    两个比较特殊的变量$*和$@表示所有位置参数

    4,位置参数实例

     

    引用和转义

    一,引用变量

    1,介绍

    在一个双引号中通过直接使用变量名的方法来引用变量,一般情况下都是没问题的。这么做将阻止所有在引号中的特殊字符被重新解释(即都被当做普通的字符串),包括变量名,但是$,`(后置引用)和“"(转义符)除外。

    保留$作为特殊字符的意义是为了能够在双引号中也能够正常的引用变量(“$variable")。

    使用双引号还能够阻止单词分割,即使这个参数包含空白,单词也不会被分隔开。如variable1="a variable containing five words"

    2,举例

    在echo语句中,只有在单词分割或者保留空白的时候,才需要把参数用双引号括起来。

     

    运行结果:

     

    IFS(Internal Field Seperator)在Linux的shell中的预设的分隔符。

    IFS是shell脚本中的一个重要概念,在处理文本数据时,它是相当有用的。内部字段分隔符是用于特定用途的定界符。IFS是存储定界符的环境变量,它是当前shell环境使用的默认定界字符串

    单引号(‘ ’)操作与双引号基本一样,但是不允许引用变量,因为$的特殊意义将被关闭。

    在单引号中,任何特殊字符都按照字面的意识进行解释,除了单引号本身。所以说单引号(全引用)是一种比双引号(部分引用)更严格的引用方法

    二,转义

    1,概念

    转义是一种引用单个字符的方法。一个签名放上转义符()的字符就是告诉shell这个字符按照字面的意思进行解释,换句话说,就是这个字符失去了它的特殊含义。

    2,转义符的含义

    在echo命令中:

      

    $表示$本身字面的含义(跟在$后边的变量名将不能引用变量的值),如:

     

    \表示反斜杠线字面的意思,如:

     

    3,一个实例

     

    运行结果

     

    4,转义符()的行为探究

    的行为依赖于它自身是否被转义,被引用(“”),或者是否会出现在命令替换或here document中。

    举例:

    运行结果:

    5,变量中的转义

    赋值给变量的字符串的元素也会被转义,但是不能把一个单独的转义符赋值给变量

     

    6,转义空格

    转移一个空格会阻止命令行参数列表的“单词分割”问题

     

    运行结果:

     

    7,续行功能

    转义符也提供续行功能,也就是编写多行命令的功能

    每个单词行都包含一个不同的命令,但是每行结尾的转义符都会转义换行符,这样下一行会与上一行一起形成一个命令序列。

     

    运行结果:

     

    如果一个脚本以 | (管道符)结束,那么就不同非的加上转义符( )了。但是一个好的编程风格,还是应该在行尾加上转义符。

     

    退出和退出状态码

    一,退出状态码

    1,退出

    exit被用来结束一个脚本,它返回一个值,并且这个值会传递给脚本的父进程,父进程会使用一个值做下一步的处理。

    2,退出状态码

    每个命令都会返回一个退出状态码(有时候也被称为返回状态)。

    成功的命令放回0,不成功的命令放回非零值,非零值通常都被解释成一个错误码。行为良好的UNIX命令、程序和工具都会返回0作为退出码来表示成功,虽然偶尔也会有例外。

    同样的,脚本中的函数和脚本本身也会返回退出状态码。在脚本或者是脚本函数中执行的最后的命令会决定退出状态码。在脚本中,exit nnn命令将会nnn退出码递给shell(nnn必须是十进制数,范围必须是0-255)

    当脚本以不带参数的exit命令来结束时,脚本的退出状态码就由脚本中最后执行的命令来决定(就是exit之前的命令)。

    3,一个例子

     

    $?指代的是上一条指令的执行结果

    不带参数的exit命令与exit $? 的效果是一样的,甚至脚本的结尾不写exit也与前两者的效果相同。

     

    二,反转一个条件的用法

    1,例子

    ! 逻辑 “非”操作符,将会反转命令或条件测试的结果,并且这会影响退出状态码。

     

    运行结果:

     

    特定的退出状态码具有保留含义,所以用户不应该在脚本中指定它。

     

    条件判断

    一,条件测试结构

    1,if/then结构

    if/then结构用来判断命令列表的退出状态符是否为0,0表示成功,如果成功的话,就执行接下来的一个或多个命令

    注意:这里与C语言等其他语言不同,不能直接使用0或者1作为判断条件,而应该以false,true代替。与其他大多数语言相反的true返回的是0,false返回的是1.

    有一个专有命令 [ (左中括号,特殊字符),这个命令与test命令等价,由于效率上的考虑,bash将它作为一个内建命令。

    注意:由于Bash的语法检查机制的原因,如果在条件测试时只使用一个[会出现一个错误提示,为了避免这个问题,我们通常将使用一对方括号包含条件测试[]

    在版本2.02的Bash中,引入了“[[...]]”扩展测试命令,[[是一个关键字,并不是一个命令。

    if命令能够测试任何命令,并不仅仅是中括号中的条件。

     

     

     

    2,多级比较(应注意与嵌套条件分支区分)

     

    运行结果:

     

    注意:((...))和let..如果运算结果为非0,该语句退出码为0,否则为1;[[...]]是作为一个单独的语句并且会返回一个退出码

    3,真假判断

     

    4,(( ))结构

    (( )) 结构扩展并计算一个算术表达式的值。如果表达式的结果为0,那么返回的退出状态符为1,或者是“假”。而一个非零值得表达式所返回的退出状态码为0,或者是“true”。

     

     

    二,文件测试操作符

    1,操作符列举

     

    举例:

     

    三,二元比较操作符

    1,整数比较

    -eq 等于

    if [ "$a" -eq "$b" ]

    -ne 不等于

    if [ "$a" -ne "$b"]

    -gt 大于

    if [ "$a -gt "$b"]

    -ge 大于等于

    if [ "$a" -ge "$b"]

    -lt 小于

    if [ "$a -lt "$b" ]

    -le 小于等于

    if [ "$a -le "$b"]

    < 小于(在双括号中使用)

    (( "$a" < " $b"))

    <=小于等于(在双括号中使用)

    (( "$a" <= "$b"))

    > (在双括号中使用)

    (( "$a > "$b" ))

    =>(在双括号中使用)

    (( "$a" => "$b"))

     

    2,字符串比较

    =等于

    if [ "$a" = "$b"]

    = =等于, 与= 等价

    if [ "$a" == "$b" ]

    < 小于,按照ASCII字符进行排序

    if [ "$a" < "$b"]]

    if [ "$a" < "$b"]]

    注意“<”使用在[]结构中的时候需要被转义

    大于,按照ASCII字符进行排序

    if [[ "$a" > "$b" ]]

    if [[ "$a" > “$b"]]

    -z字符串为“null”,意思就是字符串长度为零-n字符串不为“null"

    3,算术比较与字符串比较

    4,检查字符串是否为null

    运行结果:

     

    5,zmore

     

    6.compound和comparison

    -a逻辑与exp1 -a exp2 如果表达式exp1和exp2都为真的话那么结果为真。

    -o逻辑或exp1 -o exp2 如果表达式exp1和exp2中至少有一个为真的话,那么结果为真。

    注意:这与Bash中的比较操作符&&和||非常相像,但是这两个操作符是用在双中括号中的。

    [[ condition1 && condition2 ]]

    -o 和 -a 操作符一般都是和test命令或者是单中括号结构一起使用的

    if [ "$exp1" -a "exp2" ]

     

    操作符

    一,赋值

    1,变量赋值

    = 通用赋值操作符,可用于算术和字符串赋值。

    var=27

    vategory=minerals #在“="之后是不允许出现空白字符的。

    不要混淆=赋值操作与=测试操作符。也正是因为这一点,在bash里面测试操作也常写作==,但这可能在其他shell中是不允许的

    ----------------------------------------------------------------------

    # = 在这里是测试操作符

    if [ "$string1" = "$string2" ]

    # if [ "X$string1" = "X$string2" ] 是一种更安全的做法

    #这样可以防止两个变量中的一个为空所产生的错误

    # ( 字符“X”作为前缀在等式两边是可以互相抵消的。)

    then

    command

    fi

    ---------------------------------------------------------------------------

    二,算术操作符

    1,简单算术操作符

     

    2,求最大公约数

  • 相关阅读:
    Chrome80调整SameSite策略对IdentityServer4的影响以及处理方案(翻译)
    IdentityServer4源码解析_4_令牌发放接口
    IdentityServer4源码解析_3_认证接口
    IdentityServer4源码解析_2_元数据接口
    IdentityServer4源码解析_1_项目结构
    AspNetCore3.1_Secutiry源码解析_8_Authorization_授权框架
    AspNetCore3.1_Secutiry源码解析_7_Authentication_其他
    AspNetCore3.1_Secutiry源码解析_6_Authentication_OpenIdConnect
    AspNetCore3.1_Secutiry源码解析_5_Authentication_OAuth
    AspNetCore3.1_Secutiry源码解析_4_Authentication_JwtBear
  • 原文地址:https://www.cnblogs.com/isChenJY/p/7745573.html
Copyright © 2020-2023  润新知