• 《Linux》day3--shell语法(上)


    概述

    shell是我们通过命令行与操作系统沟通的语言
    shell脚本可以直接在命令行中执行,也可以将一套逻辑组织成一个文件,方便复用
    Linux中有很多常见的shell脚本:我们最常用的就是bash,也是Linux系统一般默认使用的。

    文件开头需要写:#! /bin/bash ---------指明bash为脚本解释器

    脚本创建示例:

    #! /bin/bash
    echo "hello world"
    
    • 1
    • 2

    运行方式:

    acs@fb883ed03006:~$ chmod +x test.sh #使脚本具有可执行权限                                                               
    acs@fb883ed03006:~$ ./test.sh #当前路径下执行                                                                        
    hello world  #脚本输出                                                                                        
    acs@fb883ed03006:~$ /home/acs/test.sh #绝对路径下执行                                                              
    hello world                                                                                          
    acs@fb883ed03006:~$ ~/test.sh   #家目录路径下执行                                                   
    hello world 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    用解释器执行(不需要权限):

    acs@fb883ed03006:~$ bash test.sh 
    hello world 
    
    • 1
    • 2

    注意:用解释器执行不需要有权限,作为可执行文件来执行一定要有权限

    注释

    单行中 # 之后的内容均是注释

    # 这是一行注释
    echo "hello world" #这也是注释
    
    • 1
    • 2

    多行注释:

    :<
    • 1
    • 2
    • 3
    • 4

    变量

    定义变量,不需要加 $ 符号,注意等号两边不可以有空格,使用变量时,变量前面要加 $ 符号
    例如:

    name1='sun' #单引号定义字符串
    name2="sun" #双引号定义字符串
    name3=sun #可以不加引号,也可以定义字符串
    
    echo $name1 #输出sun
    echo ${name1} #这种更为规范
    echo ${name1}tong #输出suntong
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    只读变量:使用readomly或者declare可以将变量设置为只读状态

    name=sun
    readonly name
    declare -r name #两种写法均可
    name=st #会报错,因为这时候name是只读变量
    
    • 1
    • 2
    • 3
    • 4

    删除变量:unset可以删除变量

    name=sun
    unset name
    echo $name #输出空行
    
    • 1
    • 2
    • 3

    变量类型

    1. 自定义变量(局部变量):子进程不能访问的变量
    2. 环境变量(全局变量):子进程可以访问的变量

    自定义变量改为环境变量

    name=sun
    export name #第一种方法
    declare -x name #第二种方法
    
    • 1
    • 2
    • 3

    环境变量改为自定义变量

    export name=sun #定义环境变量
    declare +x name #定义为自定义变量
    
    • 1
    • 2

    字符串:字符串可以使单引号,也可以是双引号,也可以不用引号

    单引号和双引号的区别:

    • 单引号的内容会原模原样的输出,不会读取变量、不会执行
    • 双引号中的内容会读取内容、会执行
    name=sun
    echo "hello, $name \"hh\"" #双引号,输出 hello,sun "hh"
    echo 'hello, $name \"hh"' #单引号,输出 hello, $name \"hh\"
    
    • 1
    • 2
    • 3

    注意:不用引号是和双引号的效果是一样的

    获取字符串长度:用 # + 字符串

    name="sun"
    echo ${#name} #输出3
    
    • 1
    • 2

    提取子串

    name="hello sun"
    echo ${name:0:5} #提取从0开始的5个字符,会输出hello
    
    • 1
    • 2

    注意:字符串的区间是左闭右开,从0开始

    默认变量

    文件参数变量

    在执行shell脚本时,可以向脚本传递参数。$1是第一个参数,$2是第二个参数,以此类推,特殊的,$0是文件名
    (包含路径)

    #! /bin/bash
    
    echo "文件名:"$0
    echo "第一个参数:"$1
    echo "第二个参数:"$2
    echo "第三个参数:"$3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    然后执行该脚本:

    acs@fb883ed03006:~$ chmod +x test.sh
    acs@fb883ed03006:~$ ./test.sh 1 2 3 4
    文件名:./test.sh
    第一个参数:1
    第二个参数:2
    第三个参数:3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意:向脚本传递参数大于一位时,需要用大括号括起来;例如 echo {10}

    其他参数相关变量

    在这里插入图片描述

    数组

    数组中可以存放多种不同类型的值,只支持一维数组,初始化时不需要指明数组的大小
    数组下标是从0开始的
    定义:数组用小括号表示,元素之间用空格隔开
    例如:

    array=(1 abc "sun" sun)
    
    • 1

    也可以直接定义数组中某个元素的值

    array[0]=1
    array[1]=abc
    array[2]="sun"
    array[3]=sun
    
    • 1
    • 2
    • 3
    • 4

    读取数组中某个元素的值

    ${array[index]}
    #例如
    echo ${array[0]}
    echo ${array[1]}
    echo ${array[2]}
    echo ${array[3]}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    读取整个数组

    ${array[@]} #第一种写法
    ${array[*]} #第二种写法
    
    • 1
    • 2

    数组长度:类似于字符串

    ${#array[@]} #第一种写法
    ${#array[*]} #第二种写法
    
    • 1
    • 2

    expr命令

    expr命令用于求表达式的值,表达式说明:

    • 用空格隔开每一项
    • 用反斜线放在shell特定的字符前面(当发现表达式运行错误时,可以试试转义)
    • 对包含空格和其他特殊字符的字符串要用引号引起来
    • expr命令会在 sdout 中输出结果,如果是逻辑表达式,若结果为真,则输出1,否则为0
    • expr命令的 exit code :如果为逻辑关系表达式,若结果为真, exit code 为0,否则为1

    字符串表达式:

    • length string – 返回字符串string的长度
    • index string charset – charset 任意单个字符在string中最前面的字符位置,下标从1开始,如果在string中完全不存在 charset 的字符,则返回0
    • substr string position length – 返回string字符串中从position开始,长度为length的子串;如果position或者length为负数、0或非数值,则返回空字符串

    例如:

    #! /bin/bash
    
    str="hello world"
    echo `expr length "$str"` #``不是单引号,表示执行该命令,输出11
    echo `expr index "$str" aWd` #输出11,下标从1开始
    echo `expr substr "$str" 2 3` #输出 ell
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    整数表达式:

    expr支持普通的算术运算,算术表达式优先级低于字符串表达式,高于逻辑关系表达式
    +/-:加减运算,两端参数会转换为整数,如果转换失败则会报错
    、* / %:乘、除、取模运算,两端参数会转换为整数,若转换失败则会报错
    ():可以改变优先级,但是需要反斜杠进行转义

    例如:

    #! /bin/bash
    
    a=3
    b=4
    
    echo `expr $a + $b` #输出7
    echo `expr $a - $b` #输出-1
    echo `expr $a \* $b` #输出12,*需要转义
    echo `expr $a / $b` #输出0,整除
    echo `expr $a % $b` #输出3
    echo `expr \( $a + 1 \) \* \( $b + 1 \)` #输出20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    逻辑关系表达式

    • | :如果第一个参数非空且非0,则返回第一个参数的值,否则返回第二个参数的值,但要求第二个参数的值也是非空或非0,否则返回0。如果第一个参数是非空或非0时,不会计算第二个参数。
    • &:如果两个参数都非空且非0,则返回第一个参数,否则返回0。如果第一个参为0或为空,则不会计算第二个参数。
    • < <= = == != >= >:比较两端的参数,如果为true,则返回1,否则返回0。”==”是”=”的同义词。”expr”首先尝试将两端参数转换为整数,并做算术比较,如果转换失败,则按字符集排序规则做字符比较。

    例如:

    #! /bin/bash
    
    a=3
    b=4
    
    echo `expr $a \> $b` #输出0,>需要转义
    echo `expr $a '<' $b` #输出1,<也需要转义,转义也可以使用单引号引起来
    echo `expr $a '>=' $b` #输出0
    echo `expr $a '<=' $b` #输出1
    
    c=0
    d=5
    echo `expr $c \& $d` #输出0
    echo `expr $a \& $b` #输出3
    echo `expr $c \| $d` #输出5
    echo `expr $a \| $b` #输出3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    read命令

    read命令用于从标准输入中读取单行数据;当读到文件结束符时,exit code 为1,否则为0
    参数说明:
    -p:后面可以接提示信息
    -t:后面跟秒数,定义输入字符的等待时间,超过等待时间后会自动忽略此命令

    例如:

    #! /bin/bash
    
    read name #读入name的值
    echo $name #输出name的值
    read -p "Please input your name: " -t 30 age #读入age的值,等待时间为30s
    echo $age #输出age的值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    echo命令

    echo命令用于输出字符串
    命令格式为:

    echo string
    
    • 1

    显示普通字符

    echo "hello suntong"
    echo hello suntong #引号可以省略
    
    • 1
    • 2

    显示转义字符

    echo "\"hello suntong\"" #注意只能使用双引号,如果使用单引号,则不能发生转义
    echo \"hello suntong\" #可以省略双引号
    
    • 1
    • 2

    在这里插入图片描述
    显示变量

    name=sun
    echo "My name is $name" #输出My name is sun
    
    • 1
    • 2

    显示换行

    echo -e "Hi\n" #-e 开启转义
    echo "sun"
    
    • 1
    • 2

    在这里插入图片描述
    显示不换行

    echo -e "Hi \c" #-e开启转义 \c不换行
    echo "sun"
    
    • 1
    • 2

    在这里插入图片描述
    显示结果定向至文件

    echo "hello world" > output.txt #将内容以覆盖的方式输出到 output.txt 中
    
    • 1

    在这里插入图片描述
    原样输出字符串,不进行转义或取变量(用单引号)

    name=sun
    echo 'hello $sun\"' #输出 hello $sun\"
    
    • 1
    • 2

    显示命令的执行结果

    echo `date`
    
    • 1

    在这里插入图片描述

    printf命令

    printf命令用于格式化输出,类似于 C\C++ 中的printf函数
    默认不会在字符串末尾添加换行符

    例如:

    #! /bin/bash
    
    printf "%10d\n" 123 #占10位,右对齐
    printf "%-102f\n" 123.1433223 #占10位,保留两位小数,左对齐
    printf "My name is %s\n" "sun" #格式化输出字符串
    printf "%d * %d = %d\n" 2 3 `expr 2 \* 3` #表达式的值作为参数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    第一个没有点,第二个输出错误

    在这里插入图片描述

    test命令与判断符号[]

    && 表示与,||表示或
    二者具有短路原则:
    expr1 && expr2:当expr1为假时,expr2直接不做了
    expr1 || expr2:当expr1为真时,expr2直接不做了
    表达式中的 exit code 为0,表示真;为非零,表示假

    test命令

    在命令行中输入 man test,可以查看test命令的用法
    test命令用于判断文件类型,以及对变量作比较
    test命令用 exit code 返回结果,而不是使用sdout;0表示真,非0表示假

    例如:

    #! /bin/bash
    
    test 2 -lt 3 #为真,返回值为0
    echo $? #输出上个命令的返回值,输出0
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    可以用来判断文件是否存在,也可以实现if语句
    在这里插入图片描述

    文件类型判断

    测试参数代表意义
    -e文件是否存在
    -f是否为文件
    -d是否为目录(文件夹)

    例如:

    acs@fb883ed03006:~$ test -e main.sh
    acs@fb883ed03006:~$ echo $?
    0
    
    • 1
    • 2
    • 3

    文件权限判断

    测试参数代表意义
    -r文件是否可读
    -w文件是否可写
    -x文件是否可执行
    -s文件是否为空文件

    例如:

    acs@fb883ed03006:~$ test -x main.sh
    acs@fb883ed03006:~$ echo $?
    0
    acs@fb883ed03006:~$ test -r homework
    acs@fb883ed03006:~$ echo $?
    0
    acs@fb883ed03006:~$ test -w homework
    acs@fb883ed03006:~$ echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    整数间的比较

    测试参数代表意义
    -eq是否相等
    -ne是否不相等
    -gt是否大于
    -lt是否小于
    -ge是否大于等于
    -le是否小于等于

    例如:

    acs@fb883ed03006:~$ a=3
    acs@fb883ed03006:~$ b=4
    acs@fb883ed03006:~$ test $a -lt $b
    acs@fb883ed03006:~$ echo $?
    0
    acs@fb883ed03006:~$ test $a -eq $b
    acs@fb883ed03006:~$ echo $?
    1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    字符串比较

    测试参数代表意义
    test -z string判断string是否为空,如果为空,则返回true
    test -n string判断string是否非空,如果非空,则返回true,(-n可以省略)
    test str1 == str2判断str1是否等于str2
    test str1 != str2判断str1是否不等于str2

    多重条件判定 (与或非)

    测试参数代表意义
    -a两条件是否同时成立 (and)
    -o两条件是否至少少一个成立(or)
    取反,如 test !-x file,当file不可执行时,返回true

    例如:

    test -r test.sh -a -w test.sh && echo  "true" || echo "false"
    
    • 1

    判断符号[]

    []与test用法几乎一模一样,更常用于if语句中;另外[[]]是[]的加强版,支持的特性更多

    例如:

    [ 2 -lt 3 ] #为真,返回0
    echo $? #返回上一条命令的返回值,输出0
    
    • 1
    • 2

    注意:

    • []中的每一项都要用空格隔开
    • 括号内的变量,最好用引号引起来
    • 括号内的常数,最好用单或双引号括起来

    例如:

    name="sun tong"
    [ $name == "sun tong" ] #错误 等价于 [ sun tong == "sun tong" ],参数太多,有空格
    [ "$name" == "sun tong" ] #正确
    
    • 1
    • 2
    • 3
  • 相关阅读:
    HTML期末学生大作业-使用HTML+CSS技术仿传智博客网站
    Feature Pyramid Networks for Object Detection(2017.4)
    Netty学习——实战篇5 Netty 心跳监测/WebSocket长连接编程 备份
    redis相关面试题
    结构体学习
    Unity VFX Output 模块详解
    Lindorm-Operator 云原生实践
    7月28日第壹简报,星期四,农历六月三十
    6.28 学习内容
    【网安专题10.11】软件安全+安全代码大模型
  • 原文地址:https://blog.csdn.net/qq_59702185/article/details/127686682