侧边栏壁纸
博主头像
xiaoming 博主等级

累死自己,卷死别人,为了小刘而努力!!!

  • 累计撰写 34 篇文章
  • 累计创建 7 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

shell 脚本入门学习笔记

Administrator
2023-12-10 / 0 评论 / 0 点赞 / 5 阅读 / 0 字 / 正在检测是否收录...

1、shell 介绍

当用户下达指令给该操作系统的时候,实际上是把指令告诉 shell,经过 shell 解释,处理后让内核做出相应的动作。系统的回应和输出的信息也由 shell 处理,然后显示在用户的屏幕上。

image-20231212153702159

1.1 shell 解析器种类

1.1.1 查看 Linux 系统支持的 shell 解析器

cat /etc/shells

image-20231212154017615

1.1.2 解析器类型

解析器类型 介绍
/bin/sh Bourne Shell,是UNIX最初使用的shell;
/bin/bash Bourne Again Shell它是Bourne Shell的扩展,简称bash,是LinuxOS默认shell,有灵活和强大的编辑接口,同时又很友好的用户界面,交互性很强;
/sbin/nologin 未登录解析器, shell设置为/sbin/nologin是用于控制用户禁止登陆系统的,有时候有些服务,比如邮件服务,大部分都是用来接收主机的邮件而已并不需要登陆
/bin/dash dash (Debian Almquist Shell) ,也是一种Unix shell。它比Bash小,只需要较少的磁盘空间,但是它的对话性功能也较少,交互性较差。
/bin/csh c Shell是c语言风格Shell
/bin/tcsh 是C Shell的一个扩展版本。

1.2 默认 shell 解析器

1.2.1 语法

echo $SHELL

含义:打印输出当前系统环境使用的Shell解析器类型

echo 用于打印输出数据到终端

$SHELL 是全局共享的读取解析器类型环境变量,全局环境变量时所有的Shell程序都可以读取的变量

1.2.2 效果

image-20231212154735604

1.3 shell 文件编写规范

1.3.1 首行格式规范

首行需要设置 Shell 解析器的类型,语法

!/bin/bash

含义:设置当前shell脚本文件采用bash解析器运行脚本代码

1.3.2 注释格式

单行注释,语法

# 注释内容

多行注释语法

:<<!
# 需注释的内容1
# 需注释的内容2
!

1.4 shell 文件常用的执行方式

  • sh 解析器执行方式

    语法: sh 脚本文件
    介绍:就是利用 sh 命令执行脚本文件,本质就是使用 Shell 解析器运行脚本文件

  • bash解析器执行方式
    语法:bash 脚本文件
    介绍:就是利用 bash 命令执行脚本文件,本质就是使用 Shell 解析器运行脚本文件

  • 仅路径执行方式
    语法:./脚本文件
    介绍:执行当前目录下的脚本文件
    注意:脚本文件自己执行需要单有可执行权限,否则无法执行

区别:sh 或 bash 执行脚本文件方式是直接使用 Shell 解析器运行脚本文件,不需要可执行权限仅路径方式是执行脚本文件自己,需要可执行权限

2、变量的定义

2.1 变量的类型

  • 系统环境变量
  • 自定义的变量
  • 特殊符号变量

2.2 系统环境变量

2.2.1 介绍

是系统提供的共享变量.是 linux 系统加载 Shell 的配置文件中定义的变量共享给所有的 Shell 程序使用

2.2.2 shell 的配置文件分类

  1. 全局配置文件

    /etc/profile
    
    /etc/profile.d/*.sh
    
    /etc/bashrc
    
  2. 个人配置文件

    当前用户/.bash_profile

    当前用户/.bashrc

一般情况下,我们都是直接针对全局配置进行操作。

2.2.3 环境变量分类

在 Linux 系统中,环境变量按照其作用范围不同大致可以分为系统级环境变量和用户级环境变量。

系统级环境变量: Shell 环境加载全局配置文件中的变量共享给所有用户所有 Shell 程序使用,全局共享

用户级环境变量: Shell 环境加载个人配置文件中的变量共享给当前用户的 Shell 程序使用,登录用户使用

2.2.4 查看当前 shell 系统环境变量

查看命令

env

效果

image-20231212160203820

2.2.5 查看 Shell 变量(系统环境变量+自定义变量+函数)

命令

set

效果

image-20231212160348141

2.2.6 常用系统环境变量

变量名称 含义
PATH 与windows环境变量PATH功能一样,设置命令的搜索路径,以冒号为分割
HOME 当前用户主目录:/root
SHELL 当前shell解析器类型:/bin/bash
HIST5ILE 显示当前用户执行命令的历史列表文件:/root/.bash_history
PWD 显示当前所在路径: /root
OLDPWD 显示之前的路径
HOSTNAME 显示当前主机名
HOSTTYPE 显示主机的架构,是i386、i686、还是x86、x64等:x86_64设置当前系统语言环境: zh_CN.UTF-8

效果

image-20231212160916372

2.3 自定义变量

2.3.1 分类

  • 自定义局部变量
  • 自定义常量
  • 自定义全局变量

2.3.2 自定义局部变量

介绍

就是定义在一个脚本文件中的变量,只能在这个脚本文件中使用的变量,就是局部变量

定义语法

var_name=value

变量定义规则

  • 变量名称可以有字母,数字和下划线组成,但是不能以数字开头
  • 等号两侧不能有空格
  • 在bash环境中,变量的默认类型都是字符串类型,无法直接进行数值运算
  • 变量的值如果有空格,必须使用双引号括起来
  • 不能使用Shell的关键字作为变量名称

查询变量值语法

#语法1:直接使用变量名查询
$var_name
#语法2:使用花括号
${var_name}
#区别:花括号方式适合拼接字符串

效果

image-20231212161728803

注意:如果my name is ​{ver2}789中var2不带花括号,系统会认为获取 $ver2789变量数据,这个变量不存在就获取不到数据,执行效果如下

image-20231212162002143

变量删除

语法

unset var_name

效果

image-20231212162146708

2.3.3 自定义常量

介绍

就是变量设置值以后不可以修改的变量叫常量,也叫只读变量

语法

readonly var_name

效果

image-20231212162410221

2.3.4 自定义全局变量

父子 Shell 环境介绍

例如:有 2 个 Shell 脚本文件 A.sh 和 B.sh
如果在 A.sh 脚本文件中执行了 B.sh 脚本文件,那么 A.sh 就是父 Shell 环境, B.sh 就是子 Shell 环境

介绍

就是在当前脚本文件中定义全局变量,这个全局变量可以在当前 Shell 环境与子 Shell 环境中都可以使用

语法

export var_name1 var_name2

2.4 特殊符号变量

2.4.1 特殊变量 $n

语法

$n

含义

用于接收脚本文件执行时传入的参数 $o 用于获取当前脚本文件名称的
​1~9,代表获取第一输入参数到第 9 个输入参数
第 10 个以上的输入参数获取参数的格式: ${数字},否则无法获取

使用

sh脚本文件  输入参数1  输入参数2 ...

2.4.2 特殊变量 $#

语法

$#

含义

获取所有输入参数的个数

2.4.3 特殊变量 ​* @

语法

$*
$@
#含义都是获取所有输入参数,用于以后输出所有参数

$*$@区别

1.不使用双引号括起来,功能一样
$*和$@获取所有输入参数,格式为:$1 $2 ... $n
2.使用双引号括起来
"$*"获取的所有参数拼接为一个字符串,格式为:"$1 $2 ... $n"
"$@"获取一组参数列表对象,格式为: "$1" "$2" ... "$n"
使用循环打印所有输入参数可以看出区别

循环语法

for var in 列表变量
do      #循环开始
  命令   #循环体
done    #循环结束

2.4.4 特殊变量 $?

语法

$?

含义

用于获取上一个 Shell 命令的退出状态码,或者是函数的返回值

每个Shell命令的执行都有一个返回值,这个返回值用于说明命令执行是否成功

一般来说,返回0代表命令执行成功,非0代表执行失败

效果

image-20231212163423512

2.4.5 特殊变量 $$

语法

$$

含义

用于获取当 Shell 环境的进程ID号

效果

查看当前 Shell 环境进程编号

ps -aux|grep bash

image-20231212163648171

2.5 自定义系统环境变量

目标
能够自定义系统级环境变量

全局配置文件 /etc/profile 应用场景

当前用户进入 Shell 环境初始化的时候会加载全局配置文件 /etc/profile 里面的环境变量,供给所有 Shell 程序使用以后只要是所有 Shell 程序或命令使用的变量,就可以定义在这个文件中

案例演示
需求

/etc/profile 定义存储自定义全局共享环境变量数据

创建环境变量步骤
1.编辑 /etc/profile 全局配置文件
#增加命令:定义变量 VAR1=VAR1 并导出为环境变量
2重载配置文件 /etc/profile ,因为配置文件修改后要立刻加载里面的数据就需要重载,语法
source /etc/profile
3.在 Shell 环境中读取系统级环境变量 VAR1

2.6 字符串变量

介绍

字符串 (String) 就是一系列字符的组合。字符串是Shell编程中最常用的数据类型之一(除了数字和字符串,也没有其他类型了)

字符串的 3 种格式
1.单引号方式
2.双引号方式,推荐
3.不用引号方式

image-20231212164131967

字符串三种格式区别

  1. 使用单引号 ' ' 的字符串:
    任何字符都会原样输出,在拼接字符串中使用变量是无效的。

    image-20231212164334884

  2. 由双引号 " " 包围的字符串:
    其中包含了变量,那么该变量会被解析得到值,而不是原样输出。

    字符串中还可以出现双引号的子字符串,但是需要转义。

    image-20231212164519490

  3. 不被引号包围的字符串
    不被引号包围的字符串中出现变量时也会被解析,这一点和双引号 " " 包围的字符串一样。

    字符串中不能出现空格,否则空格后边的字符串会作为其他命令解析。

    image-20231212164653998

2.6.1 获取字符串的长度

语法

${#字符串变量名}

含义

获取字符串的字符长度

效果

image-20231212165618360

2.6.2 字符串的拼接

字符串的拼接方式

  • 无符号拼接
  • 双引号拼接
  • 混合拼接

效果

image-20231212170009911

2.6.3 字符串的截取

语法

格式 说明
${变量名:start : length} 从string字符串的左边第start 个字符开始,
向右截取length 个字符。start从0开始
${变量名:start} 从string字符串的左边第start个字符开始截取,直到最后。
${变量名:0-start : length} 从string字符串的右边第start个字符开始,
向右截取length 个字符。start从1开始,代表右侧第一个字符
${变量名:0-start} 从string字符串的右边第start个字符开始截取,直到最后。
${变量名#*chars} 从string 字符串左边第一次出现*chars的位置开始,
截取 *chars右边的所有字符。
${变量名##*chars} 从string 字符串左边最后一次出现*chars的位置开始,
截取 *chars右边的所有字符。
${变量名%chars*} 从string 字符串右边第一次出现chars*的位置开始,
截取chars *左边的所有字符。
${变量名%%chars *} 从string字符串右边最后一次出现chars*的位置开始,
截取chars *左边的所有字符

2.7 索引数组变量

2.7.1 数组的定义

语法

在 Shell 中,用 ( ) 来表示数组,数组元素之间用空格来分割

array_name=(item1 item2 ...) # 方式1
array_name=([索引下标1]=item1 [索引下标2]=item2 ...) # 方式2

注意:赋值号 =两边不能有空格

效果

1.定义数字存储 100,3,22,58,77,17,20

nums=(29 100 13 8 91 44)

2.Shell 是弱类型的,它并不要求所有数组元素的类型必须相同

arr=(20 56 "http")

Shell 数组元素定义后不是固定的,定义后还可以赋值

arr[6]=100

2.7.2 数组的获取

语法

1.通过下标获取元素值,index 从 0 开始

${arr[index]}

注意使用 {}

⒉.获取值同时复制给其他变量

item=${arr[index]}

3.使用 @ 或 * 可以获取数组中的所有元素

${arr[@]}
${arr[*]}

4.获取数组的长度或个数

${#arr[@]}
${#arr[*]}

5.获取数组指定元素的字符长度

${#arr[索引]}

2.7.3 数组的删除

介绍

删除数组指定元素数据和删除整个数组数据

语法

删除数组指定元素数据

unset array_name[index]

删除整个数组

unset array_name

效果

image-20231212202051301

3、shell内置命令

Shell 内置命令,就是由 Bash Shell 自身提供的命令,而不是文件系统中的可执行脚本文件。使用 type 来确定一个命令是否是内置命令:

type 命令

image-20231212202212321

通常来说,内置命令会比外部命令执行得更快,执行外部命令时不但会触发磁盘 IO,还需要 fork 出一个单独的进程来执行,执行完成后再退出。而执行内置命令相当于调用当前 Shell 进程的一个函数,还是在当前 Shell 环境进程内,减少了上下文切换。

命令 说明
: 扩展参数列表,执行重定向操作
. 读取并执行指定文件中的命令(在当前shell环境中)
alias 为指定命令定义一个别名
bg 将作业以后台模式运行
bind 将键盘序列绑定到一个readline函数或宏
break 退出tbr、while、select或until循环
builtin 执行指定的 shell内建命令
caller 返回活动子函数调用的上下文
cd 将当前目录切换为指定的目录
command 执行指定的命令,无需进行通常的shell查找
compgen 为指定单词生成可能的补全匹配
complete 显示指定的单词是如何补全的
compopt 修改指定单词的补全选项
continue 继续执行for、while、select或until循环的下一次迭代
declare 声明一个变量或变量类型。
dirs 显示当前存储目录的列表
disown 从进程作业表中删除指定的作业
echo 将指定字符串输出到STDOUT
enable 启用或禁用指定的内建shell命令
eval 将指定的参数拼接成一个命令,然后执行该命令
exec 用指定命令替换shell进程
exit 强制shell以指定的退出状态码退出
export 设置子shell进程可用的变量
fc 从历史记录中选择命令列表
fg 将作业以前台模式运行
getopts 分析指定的位置参数
hash 查找并记住指定命令的全路径名
help 显示帮助文件
history 显示命令历史记录
jobs 列出活动作业
kill 向指定的进程ID(PID)发送一个系统信号
let 计算一个数学表达式中的每个参数
local 在函数中创建一个作用域受限的变量
logout 退出登录shell
mapfile 从STDIN读取数据行,并将其加入索引数组
popd 从目录栈中删除记录
printf 使用格式化字符串显示文本
pushd 向目录栈添加一个目录
pwd 显示当前工作目录的路径名
read 从STDIN读取一行数据并将其赋给一个变量
readarray 从STBIN 读取数据行并将其放入索引数组
readonly 从STDIN读取一行数据并将其赋给一个不可修改的变量
return 强制函数以某个值退出,这个值可以被调用脚本提取
set 设置并显示环境变量的值和shell属性
shift 将位置参数依次向下降一个位置

3.1 alias 设置别名

介绍

alisa 用于给命令创建别名
好处:可以将经常操作比较复杂的命令进行设置别名,通过别名的操作提高工作效率

若该命令且不带任何参数,则显示当前Shell进程中的所有别名列表。

image-20231212203614320

上面是系统为了方便命令操作默认将部分命令创建为别名 ll 的命令与 ls -1 的效果一样,就是因为 ll 是别名

语法

alias 别名="命令"

这里使用单引号或双引号都可以

删除指定的别名

unalias 别名

删除当前 Shell 环境中所有的别名

unalias -a

注意:以上2种方式删除都是临时删除当前 Shell 的别名,如果想永久删除必须去配置文件中手动删除

别名永久生效

打开 /root/.bashrc 文件

写入需要的起别名

alias 别名="命令"

image-20231212204112207

3.2 echo 输出字符串

介绍
echo 是一个 Shell 内置命令,用于在终端输出字符串,并在最后默认加上换行符
语法
默认输出换行语法

echo 字符串

输出不换行语法

echo -n 字符串

效果

echo 输出转义字符

\n 转义字符
用于 echo 输出字符串非结尾处的换行,但是默认 echo 无法解析 /n 转义字符

演示
image-20231212204645824

-e 参数

用于解析转义字符

echo -e '字符串中含有转义字符'

演示

image-20231212204744008

3.3 read 读取控制台输入

介绍
read 是 shell 内置命令,用于从标准输入中读取数据并赋值给变量。如果没有进行重定向,默认就是从终端控制台读取用户输入的数据;如果进行了重定向,那么可以从文件中读取数据。

语法

read [-options] [var1 var2 ...]

options表示选项,如下表所示;var表示用来存储数据的变量,可以有一个,也可以有多个
optionsvar都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量 REPLY 变量中。

$REPLY保存read最后一个读入命令的数据

选项 说明
-a array 把读取的数据赋值给数组array,从下标0开始
-d delimiter 用字符串delimiter指定读取结束的位置,而不是一个换行符(读取到的数据不包括delimiter)
-e 在获取用户输入的时候,对功能键进行编码转换,不会直接显式功能键对应的字符
-n num 读取num个字符,而不是整行字符。
-p prompt 显示提示信息,提示内容为prompt。
-r 原样读取(Raw mode),不把反斜杠字符解释为转义字符。
-s 静默模式(Silent mode),不会在屏幕上显示输入的字符。
当输入密码和其它确认信息的时候,这是很有必要的。
-t seconds 设置超时时间,单位为秒。如果用户没有在指定时间内输入完成,
那么read将会返回一个非0的退出状态,表示读取失败。
-u fd 使用文件描述符fd作为输入源,而不是标准输入,类似于重定向。

3.4 exit 退出

介绍

exit 用于退出当前 Shell 环境进程结束运行,并且可以返回一个状态码.一般使用 $? 可以获取退出状态码

语法

正确退出语法

exit  # 默认返回状态码0,一般代表命令执行成功

错误退出语法

exit 非O数字  # 数字建议的范围O~255,一般代表命令执行失败

exit 应用场景
1.结束当前 Shell 进程
2.当 Shell 进程执行出错退出时,可以返回不同的状态值代表不同的错误

比如执行一个脚本文件里面操作一个文件时,可以返回1表示文件不存在,2表示文件没有读取权限,3表示文件类型不对。

3.5 declare 设置变量

介绍

declare 命令用于声明 shell 变量。可用来声明变量并设置变量的属性,也可用来显示 shell 函数
若不加上任何参数,则会显示全部的 shell 变量与函数(与执行 set 指令的效果相同)。

declare 命令作用
1.declare 设置变量的属性[重要]

2.查看全部 Shell 变量与函数

3.实现关联数组变量

3.5.1 declare 设置变量的属性

语法

declare [+/-][aArxif][变量名称=设置值]

+/- "-"可用来指定变量的属性,"+"则是取消变量所设的属性。

a array,设置为普通索引数组

A Array,设置为key-value关联数组

r readonly,将变量设置为只读,也可以使用readonly

× exprot,设置变量成为全局变量,也可以使用exportI

i int,设置为整型变量。

f function,设置为一个函数变量

3.5.2

语法

关联数组也称为"键值对((key-value)“数组,键(key) 也即字符串形式的数组下标,值 (value)也即元素值。

declare -A 关联数组变量名=([字符串key1]=值1 [字符串key2]=值2 ...)

declare也可以用于定义普通索引数组,-a参数创建普通或索引数组 -A创建关联数组

declare -a 索引数组 变量名=(值1 值2 ...)
declare -A 关联数组 变量名=([0]=值1 [1]=值2 ...)

获取指定 key 的值

${关联数组变量名[key]}

获取所有值

${关联数组变量名[*]} # 方式1
${关联数组变量名[@]} # 方式2

3.6 test 命令

介绍

Shell 中的 tes t命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

功能与 [] 一样

整数比较测试

语法

if test 数字1 options 数字2 
then
...
fi

options具体如下

参数 说明
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真

字符产比较测试

语法

参数 说明
=或== 等于,等于返回0代表成功,否则返回1代表失败不等于
!= 不等于
\ < 小于
\ > 大于
-z 字符串 字符串的长度为零则为真
-n 字符串 字符串的长度不为零则为真

文件测试

语法

参数 说明
-e 文件名 exists,如果文件存在则为真
-r文件名 read,如果文件存在且可读则为真
-w文件名 write,如果文件存在且可写则为真
-x文件名 execute,如果文件存在且可执行则为真
-s文件名 string,如果文件存在且至少有一个字符则为真
-d文件名 directory,如果文件存在且为目录则为真
-f文件名 file,如果文件存在且为普通文件则为真
-c文件名 character,如果文件存在且为字符型特殊文件则为真
-b文件名 如果文件存在且为块特殊文件则为真

4、运算符

4.1 算数运算符

介绍

expr 是 evaluate expressions 的缩写,译为"求值表达式"。Shell expr 是一个功能强大,并且比较复杂的命令,它除了可以实现整数计算,还可以结合一些选项对字符串进行处理,例如计算字符串长度、字符串比较、字符串匹配、字符串提取等,后续讲解。

语法

计算语法

expr 算术运算符表达式

注意:运算表达式

获取计算结果赋值给新变量语法

result=`expr 算术运算符表达式`

效果

image-20231213125332856

注意:运算符表达式中每个数字与符号之间要有空格

算术运算符介绍

下表列出了常用的算术运算符,假定变量 a 为 1,变量 b 为 2:

运算符 说明 举例
+ 加法 expr $a + $b结果为3
- 减法 expr $a - $b结果为-1
* 乘法 expr $a \* $b结果为2
/ 除法 expr $b / $a结果为2
% 取余 expr $b % $a结果为0
= 赋值 a=$b将把变量b的值赋给a

四则运算中如果使用了 (),也需要转义 \( 1 +1 \)

4.2 比较运算符

4.2.1 整数比较运算符

语法

下表列出了常用的比较运算符,假定变量 a 为 1,变量 b 为 2:

运算符 说明 举例
-eq equals检测两个数是否相等,相等返回0,否则返回1。 [​a -eq b ]返回1。
-ne not equals检测两个数是否不相等,不相等返回true。 [​a -ne b ]返回0。
-gt greater than检测左边的数是否大于右边的,
是返回0,否则1
[​a -gt b ]返回1。
-lt lower than检测左边的数是否小于右边的,
是返回0,否则1
[​a -lt b ]返回0。
-ge greater equals检测左边的数是否大于等于右边的,
是返回0,否则1
[​a -ge b ]返回1。
-le lower equals检测左边的数是否小于等于右边的,
是返回0,否则1
[​a -le b ]返回0。
< 检测左边的数是否小于右边的,
是返回0,否则1
((​a<b))返回0
<= 检测左边的数是否小于等于右边的,
是返回0,否则1
((​a<=b))返回0
> 检测左边的数是否大于右边的,
是返回0,否则1
((​a>b))返回1
>= 检测左边的数是否大于等于右边的,
是返回0,否则1
((​a>=b))返回1
== 检测左边的数是否等于右边的,
是返回0,否则1
((​a==b))返回1
!= 检测左边的数是否不等于右边的,
是返回0,否则1
((​a ! =b))返回0

注意:
整数比较运算符只支持整数,不支持小数与字符串(字符串比较后续讲解),除非字符串的值是整数数字。每个命令都有返回值,这个后面我们会讲解退出状态再具体说明,返回0代表成功,返回1代表失败

4.2.2 字符串比较运算符

介绍
可以比较 2 个变量,变量的类型可以为数字(整数,小数)与字符串

语法
下表列出了常用的字符串运算符,假定变量 a 为 "abc" ,变量 b 为 "efg" :

字符串比较可以使用 [[]] 和 [] 2种方式

运算符 说明 举例
==或= 相等。用于比较两个字符串或数字,相同则返回0。可以使用= [ $a == $b ]返回1
[ $a = $b ]返回1
[[ $a ==$b ]]返1
[[ $a = $b ]]返回1
!= 不相等。用于比较两个字符串或数字,不相同则返回0。 [ $a != $b ]返回0
[[ $a != $b ]]返回0
< 小于,用于比较两个字符串或数字,小于返回0,否则返回1 [ $a < $b ]返回0
[[ $a < $b ]]返回0
-z 检测字符串长度是否为0,如果长度为0返回则返回0,否则返回1。 [ -z $a ]返回false。
-n 检测字符串长度是否不为0,如果长度不为О则返回0,否则返回 [ -n "$a" ]返回true。
$ 检测字符串是否为空,不为空返回true。 [ $a ]返回true。

字符串比较没有可以通过 [[ "a" < "b" && "a" == "b” ]]

4.2.3 [[]] 和 [] 的区别

区别1: word splitting 的发生

区别说明

  • [[]] 不会有 word splitting 发生
  • [] 会有 word splitting 发生

word splitting 介绍

会将含有空格字符串进行分拆分割后比较

效果

image-20231213131944856

区别2:转义字符区别说明
[[]] 对 < 不需要转义,格式为 [[ 字符串1 < 字符串2 ]]

[] 需要对 < , > 转义,格式为 [字符串1 < 字符串2 ]

效果

[] 效果

image-20231213132258969

[[]] 效果

image-20231213132418935

4.3 布尔运算符

介绍

运算符 说明 举例
! 非运算,取反,表达式为true则返回false,
否则返回true。
[ ! 表达式 ]取反。
-o or或运算,有一个表达式为true则返回true。 [ 表达式1 -o 表达式2 ]
-a and 与运算,两个表达式都为true才返回true。 [ 表达式1 -a 表达式2 ]

注意布尔运算符放在[]或与test命令配合使用才有效

布尔运算符常与与test命令配合使用,后续讲解

4.4 逻辑运算符

介绍

运算符 说明 举例
&& 逻辑的AND [[ 表达式1 && 表达式2 ]]
ll 逻辑的OR `[[ 表达式1
! 逻辑非 [[ ! 表达式 ]]

注意
使用 && 和 || 的运算符必须放在 [[]] 或 (()) 中才有效,否则报错

! 可以用在 [],[[]] 中,不可以在 (())

4.5 文件测试运算符

linux 文件系统类型介绍

-︰普通文件
d:目录文件

l:链接文件

b:块设备文件

c:字符设备文件
p:管道文件

文件

测试运算符用于检测文件的各种属性。属性检测描述如下:

操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回true。 [ -b $file ]返回false。
-c file 检测文件是否是字符设备文件,如果是,则返回true。 [ -c $file ]返回false。
-d file directory,检测文件是否是目录,如果是,则返回true。 [ -d $file ]返回false。
-f file file,检测文件是否是普通文件(既不是目录,也不是设备文件)
,如果是,则返回true。
[ -f $file ]返回true。
-g file 检测文件是否设置了SGID位,如果是,则返回true。 [ -g $file ]返回false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,
则返回true。
[ -k $file ]返回false。
-p file 检测文件是否是有名管道文件,如果是,则返回true。 [ -p $file ]返回false。
-u file 检测文件是否设置了SUID位,[如果是,则返回true。 [ -u $file ]返回false。
-r file read,检测文件是否可读,如果是,则返回true。 [ -r $file ]返回true。
-w file write,检测文件是否可写,如果是,则返回true。 [ -w $file ]返回true。
-x file execute,检测文件是否可执行,如果是,则返回true。 [ -x $file ]返回true。
-s file size,检测文件是否为空(文件大小是否大于0)
,不为空返回true。
[ -s $file ]返回true。
-e file exists,检测文件(包括目录)是否存在,如果是,
则返回true。
[ -e $file ]返回true。
file1 -nt file2 new than(nt), file1是否比file2新 [ file1 -nt file2 ]
file1 -ot file2 old than(ot), file1是否比file2旧 [ file1 -ot file2 ]

其他检查符:
-S:判断某文件是否 socket。
-L: link,检测文件是否存在并且是一个符号链接。

语法

[ options文件路径字符串 ]
或
[[ options 文件路径字符串 ]]

5、shell 计算命令

5.1 expr 命令

介绍
expr (evaluate expressions的缩写),译为“表达式求值"。Shell expr 是一个功能强大,并且比较复杂的命令,它除了可以实现整数计算,还可以结合一些选项对字符串进行处理,例如计算字符串长度、字符串比较、字符串匹配、字符串提取等.

求值表达式(已讲)
计算语法

expr算术运算符表达式
#例如:expr 1 + 1 返回: 2
#例如: exbr \( 10 + 10 \)\* 2 + 100 返回:140

获取计算结果赋值给新变量语法

resu1t='expr算术运算符表达式`
#例如: result='expr 1 + 1` 输出resu1t得到结果: 2

字符串语法

计算字符串的长度语法

expr length 字符串
#例如:expr length "itheima" 返回: 7

截取字符串语法

expr substr 字符串 start end
# start截取字符串的起始位置,从1开始
#end截取字符串的结束位置,包含这个位置截取
#例如 expr substr "itheima" 1 2 返回:it

获取第一个字符在字符串中出现的位置语法

expr index被查找字符串需要查找的字符
#例如 expr index "itheima" t 会返回: 2

正则表达式匹配1语法

expr match 字符串 正则表达式
#正则表达式默认带有^,代表以什么开头#返回值为符合匹配字符的长度,否则返回为0
#例如: expr match "itheima" ".*m" 会返回: 6
#正则表达式通配符"."代表任意一个字符
#正则表达式通配符"*"代表签名的字符可以出现0到多次
# ".*m"含义为匹配字符串中m前面的字符串长度

正则表表达式匹配2语法,功能与语法1一样

expr 字符串 : 正则表达式
#正则表达式默认带有^,代表以什么开头
#返回值为符合匹配字符的长度,否则返回为0
#例如: expr "itheima" : ".*m" 会返回: 6

5.2 (()) 命令

介绍
双小括号 (()),用于进行数学运算表达式的执行,将数学运算表达式放在 (( 和 )) 之间。

可以使用 ​ 获取 (()) 表达式命令的结果,这和使用 获得变量值是一样的。

语法

((表达式))

用法

运算操作符/运算命令 说明
((a=1+6))
((b=a-1))
((c=a+b))
这种写法可以在计算完成后给变量赋值。以((b=a-1))为例,
即将a-1的运算结果赋值给变量c。注意,使用变量时不用加$前缀,
(())会自动解析变量名。
a=​((1+6)<br/>b=((a-1))
c=$((a+b))
可以在(())前面加上S符号获取(())命令的执行结果,
也即获取整个表达式的值。以c=​((a+b))为例,即将a+b这个<br/>表达式的运算结果赋值给变量c。注意,如果c=((a+b))这样的写<br/>法是错误的,不加就不能取得表达式的结果。
((a>7&& b==c)) (( ))也可以进行逻辑运算,在if语句中常会使用逻辑运算。
echo $((a+10)) 需要立即输出表达式的运算结果时,可以在(())前面加$符号。
((a=3+5, b=a+10)) 对多个表达式同时进行计算,多表表达式使用","号隔开

注意:符号之间有无空格都可以,((a = 1+6)[等价于((a = 1+6))

5.3 let 命令

介绍
let 命令和双小括号 (()) 在数字计算方面功能一样.但是没有 (()) 功能强大, let 只能用于赋值计算,不能直接输出,不可以条件判断

语法

let 赋值表达式

注意
1.语法功能等价于((表达式))
2.多个表达式之间使用空格不是","号
3.对于类似let a+b这样的写法,Shell虽然计算了a+b的值,但却将结果丢弃,如果echo let a+b 会直接输出字符串a+b;若不想这样,可以使用1et sum=a+b将a+b的结果保存在变量sum中。

image-20231217193521915

输出建议使用(())

小结
let 数字计算用法
作用:用于赋值,是最简洁的整数运算赋值命令

计算赋值用法: let 变量名=整数运算表达式
多个表达式计算赋值用法: let 变量名1=整数运算表达式1 变量名2=整数运算表达式2 ...

5.4 $[] 命令

介绍
和 (())、let 命令类似,$[] 也只能进行整数运算。但是只能对单个表达式的计算求值与输出

语法

$[表达式]

1.$[]会对表达式进行计算,并取得计算结果

2.表达式内部不可以赋值给变量

示例
calculate4.sh 脚本代码

#!/bin/bash

#计算1+6赋值给变量a
a=$[1+6]
#计算变量a-1赋值给变量b
b=$[a-1]
#计算变量a+变量b赋值给变量c
c=$[a+b]

小结

执行整数表达式命令的总结,推荐使用哪个

expr
	优点:可以直接输出
	缺点:计算表达式里面引用变量使用$,特殊字符需要转义只能计算一个表达式
(())(直接求值输出推荐方式)
	优点:直接输出,里面直接使用变量名,特殊字符不需要转义,多个表达式赋值
	缺点:需要获取值以后才可以输出
let(赋值推荐方式)
	优点:赋值简单,特殊字符不需要转义,
	缺点:不能直接输出
$[]
	优点: 特殊字符不需要转义
	缺点:不能多表达是计算

5.5 bc 命令

作用
通常在 linux 下 bc 当计算器用,具体有3个用法

1.bc 中互动式的数学运算
2.shell 中非互动式的管道运算
3.shell 中非互动式的输入重定向运算

介绍
Bash shell 内置了对整数运算的支持,但是并不支持浮点运算,而 linux bc (basic calculator) 命令可以很方便的进行浮点运算. bc 命令是Linux 简单的计算器,能进行进制转换与计算。能转换的进制包括十六进制、十进制、八进制、二进制等。可以使用的运算符号包括 (+) 加法、(-) 减法、(*) 乘法、(/) 除法、(^) 指数、(%) 余数等

bc 命令
语法

bc [options] [参数]

options

选项 说明
-h help,帮助信息
-v version,显示命令版本信息
-l mathlib,使用标准数学库,例如使用内置函数就需要使用这个参数
-i interactive,强制交互
-w warn,显示POSIX的警告信息
-s standard,使用POSIX标准来处理
-q quiet,不显示欢迎信息

默认使用bc命令后回车会有很多欢迎信息,可以便用bc -q回车不会有欢迎信息

参数
文件:指定包含计算任务的文件。

示例:bc 执行计算任务的文件
创建 task.txt 文件,编辑文件内容(一个计算表达式一行)

108*67+12345
58+2007*11

执行命令

image-20231217194651389

可以使用quit命令退出bc

内置变量

变量名 作用
scale 指定精度,也即小数点后的位数;默认为0,也即不使用小数部分。
ibase 指定输入的数字的进制,默认为十进制,
obase 指定输出的数字的进制,默认为十进制
last或者. 获取最近计算打印结果的数字

内置数学函数

函数名 作用
s(x) 计算x的正弦值,×是弧度值。
C(x) 计算x的余弦值,×是弧度值。
a(x) 计算×的反正切值,返回弧度值。
l(x) 计算×的自然对数。
e(x) 求e的×次方。
j(n, x) 贝塞尔函数,计算从n到×的阶数。

示例

image-20231211210646823

image-20231211210906080

image-20231211210938562

image-20231211211017105

image-20231211211104370

image-20231212104201926

image-20231212104237112

6、流程控制

6.1 if else 语句

6.1.1 if语句

多行写法语法

if 条件
then
	命令
fi

可以将if语句放入一行语法

if 条件; then 命令; fi

6.1.2 if else 语句

if 条件
then
	命令
else
	命令
fi

6.1.3 if elif else 语句

if 条件1
then
	命令1
e1lf 条件2
then
	命令2
elif 条件3
then
	命令3
	...
else
	命令N
fi

6.2 if 条件判判断句的退出状态

介绍

linux 任何命令的的执行都会有一个退出状态,无论是内置命令还是外部文件命令.还是自定义的 Shell 函数,当它退出(运行结束)时,都会返回一个比较小的整数值给调用(使用)它的程序,这就是命令的退出状态
大多数命令状态0代表成功,非0代表失败.也有特殊的命令,比如 diff 命令用来比较两个文件的不同,对于“没有差别"的文件返回0,对于“找到差别"的文件返回1,对无效文件名返回2
Shell 中,有多种方式取得命令的退出状态,其中 $? 是最常见的一种.

image-20231217200107707

退出状态和逻辑运算符的组合
Shell if 语句使用逻辑运篁符将多个退出状态组合起来.这样就可以一次判新多个条件了.

运算符 使用格式 说明
&&或-a 条件1&&条件2 逻辑与运算符,当条件1和条件2同时成立时,
整个表达式才成立。如果检测到条件1的退出状态为0,
就不会再检测条件2了,因为不管条件2的退出状态是什么,
整个表达式必然都是不成立的,检测了也是多此一举。
||或-o 条件1||条件2 逻辑或运算符,条件1和条件2两个表
达式中只要有一个成立,整个表达式就成立。如果检
测到条件1的退出状态为1,就不会再检测条件2了,因为
不管条件2的退出状态是什么,整个表达式必然都是成立的,
检测了也是多此一举。
! !条件 逻辑非运算符,相当于“取反"的效果。如果条件成立,那么整
个表达式就不成立;如果条件不成立,那么整个表达式就成立。

6.3 case 语句

介绍
Shell case 语句为多选择语句。可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令;

当分支较多,并且判断条件比较简单时,使用 case in 语句就比较方便了。

语法

case 值 in
匹配模式1)
	命令1
	命令2
	...
	;;
匹配模式2)
	命令1
	命令2
	...
	;;
*)
	命令1
	命令2
	...
	;;
esac

每一匹配模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,中间的所有命令开始执行直至;(类似 break ,不可以替代否则语法报错)。取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号*捕获该值,再执行后面的命令。
case、in 和 esac 都是 Shell 关键字 ,esac 就是 case 的反写在这里代表结束 case
匹配模式:可以是一个数字、一个字符串,甚至是一个简单正则表达式。
简单正则表达式支持如下通配符

格式 说明
* 表示任意字符串。
[abc] 表示a、b、c三个字符中的任意一个。比如,[15ZH]表示1、5、Z、H四个字符中的任意一个。
[m-n] 表示从m到n的任意一个字符。比如,[0-9]表示任意一个数字,[0-9a-zA-Z]表示字母或数字。
| 表示多重选择,类似逻辑运算中的或运算。比如,abc| xyz表示匹配字符串"abc"或者"xyz"。

6.4 while 语句

介绍

while 用于循环执行一系列命令

语法
多行写法

while 条件
do
    命令1
    命令2
    ...
    continue; #结束当前这一次循环,进入下一次循环
    break; #结束当前循环
done

一行写法

while 条件; do 命令; done;

无限循环

while
do
    command
done

while true
do
	command
done

6.5 until 语句

介绍
until 也是循环结构语句,unti l循环与 while 循环在处理方式上刚好相反,循环条件为 false 会一致循环,条件为 true 停止循环.
语法

until 条件
do
	命令
done

条件如果返回值为1(代表false),则继续执行循环体内的语句,否则跳出循环。

6.6 for语句

循环方式1

语法
多行写法

for var in item1 item2 ... itemN
do
    命令1
    命令2
    ...
done

一行写法

for var in item1 item2 ... itemN; do 命令1; 命令2...; done;

var是循环变量
item1 item2 ...itemN是循环的范围

循环方式2

语法
多行写法

for var in {start..end}
do
	命令
done

start:循环范围的起始值,必须为整数
end:循环范围的结束值,必须为整数

一行写法

for var in istart..end}; do 命令; done

循环方式3

语法
多行写法

for((i=start;i<=end; i++))
do
	命令
done

一行写法

for((i=start;i<=end;i++)); do 命令; done

image-20231217201808602

6.7 select 语句

介绍
select in 循环用来增强交互性,它可以显示出带编号的菜单,用户输入不同的编号就可以选择不同的菜单,并执行不同的功能 select in 是 Shell 独有的一种循环,非常适合终端(Terminal)这样的交互场景,其他语言没有;
语法

select var in menu1 mnu2 ...
do
	命令
done

注意:select,是无限循环(死循环),输入空值,或者输入的值无效,都不会结束循坏,只有遇到break语句,或者按下Ctrl+D组合键才能结束循环。
执行命令过程中:终端会输出#?代表可以输入选择的菜单编号

脚本文件代码

#! /bin/bash
echo "你的爱好是什么"
select hobby in "编程" "游戏" "篮球" "游泳"
do
    case $hobby in
    "编程")
    	echo "编程,多敲代码”
    	break
    	;;
    "游戏")
    	echo "少玩游戏"
    	break
    	;;
    "篮球"|"游泳")
    	echo "运动有利健康"break
		;;
	*)
		echo "输入错误,请重新输
	esac
done

7、shell 函数

7.1 系统函数

函数介绍
Shell 编程和其他编程语言一样,有函数,函数是由若干条 shell 命令组成的语句块,实现 Shell 脚本代码重用和模块化编程。
函数分类
1.系统函数

2.自定义函数

7.1.1 basename 系统函数

介绍
basename 函数用于获取文件名的函数,根据给出的文件路径截取出文件名
语法

basename [string / pathname] [suffix]

根据根据指定字符串或路径名进行截取文件名,比如:根据路径"lone/twolaa.txt",可以截取出aa.txt

suffix:用于截取的时候去掉指定的后缀名.

image-20231217203027252

7.1.2 dirname 系统函数

介绍
从指定的文件绝对路径,去除文件名,返回剩下的前缀目录路径
语法

dirname 文件绝对路径

image-20231217203112811

7.2 自定义函数

语法

#函数的定义
[ function ] funname ()
{
    命令
    [return 返回值]
}
#调用函数
funname 传递参数1 传递参数2 ...

1.可以带function fun()定义,也可以直接fun()定义,不带任何参数。
2参数返回,可以显示加: return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0~255)

注意
必须在调用函数地方之前,先声明函数,shell 脚本是逐行运行,只要先运行了函数,后面才可以时使用函数

示例:无参无返回值函数
文件脚本代码

#!/bin/bash
demo()
{
	echo "执行了函数"
}

#调用函数
demo

image-20231217203333857

示例:无参有返回值函数
fun2.sh 文件脚本代码

#!/bin/bash
sum()
{
    echo "求两个数的和..."
    read -p "输入第一个数字: " n1
    read -p "输入第二个数字: " n2
    echo "两个数字分别为$n1 和 $n2 "
    return $(($n1+$n2))
}
#调用函数
sum
echo "两个数字的和为: $? " #获取函数返回值

image-20231217203541174

示例:有参函数

介绍
在 Shell 中,调用函数时可以向其传弟参数。在函数体内部,通过 Sn 的形式来获取参数的值,例如,​1 表示第一个参数,2 表示第二个参数.
其他参数介绍

参数处理 说明
$# 传递到脚本或函数的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
#!/bin/bash
funParam()
{
    echo "第一个参数为 $1 ! "
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 ! "
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !
}
#调用函数
funParam 1 2 3 4 5 6 7 8 9 10 22

image-20231217203915528

8、shell 重定向

重定向介绍

标准输入介绍
从键盘读取用户输入的数据,然后再把数据拿到 Shell 程序中使用;
标准输出介绍
Shell 程序产生的数据,这些数据一般都是呈现到显示器上供用户浏览查看;

默认输入输出文件
每个 Unix/Linux 命令运行时都会打开三个文件.文件如下

文件名 类型 文件描述符(file description, fd) 功能
stdin (standard input)
标准输入文件
0 获取键盘的输入数据
stdout (standard output)
标准输出文件
1 将正确数据输出到显示器上
stderr (standard error)
标准错误输出文件
2 将错误信息输出到显示器上

每个文件都有一个唯一的文件描述符fd,后面会通过唯一文件描述符fd操作对应的信息

Shell 程序操作输入输出时用到这3个文件
1.Shell 程序默认会从 stdin 文件中读取输入数据

2.Shell 程序默认会向 stdout 文件输出正确数据

3.Shell 程序默认会项 stderr 文件中输出错误信息

这3个文件用于临时传输数据使用

重定向输入输出介绍
1.标准输入是数据默认从键盘流向程序,如果改变了它的方向,数据就从其它地方流入,这就是输入重定向。

2.标准输出是数据默认从程序流向显示器,如果改变了它的方向,数据就流向其它地方,这就是输出重定向。

Linux Shell 重定向分为两种,一种输入重定向,一种是输出重定向;

重定向的作用
输出重定向是指命令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中。这样做的最大好处就是把命令的结果保存起来,当我们需要的时候可以随时查询。

重定向语法

命令 说明
命令>file 将正确数据重定向输出到file文件中,覆盖方式
命令<file 将输入重定向从file文件中读取数据
命令>>file 将正确数据重定向输出到 file文件中,追加方式
命令< file1 > file2 从file文件读取数据,输出数据到file2文件中
命令fd> file 根据指定的文件描述符fd将数据重定向输出到file文件中,覆盖方式
命令fd>> file 根据指定的文件描述符fd 将数据重定向输出到file 文件中,追加方式
命令> file fd1>&fd2 将fd1和fd2文件描述符合并输出到文件。
fd1<& fd2 将fd1和fd2文件描述符合并从文件读取输入
<<tag 读取终端输入数据,将开始标记tag和结束标记tag之间的内容作为输入。
标记名tag可以任意

在输出重定向中,>代表的是覆盖输出,>>代表的是追加输出。
fd是文件描述符
0通常是标准输入(STDIN) ,

1是标准输出(STDOUT) ,

2是标准错误输出(STDERR)。

fd>或fd>> 中间不可以有空格

输入示例:统计文件数据行数

wc 命令介绍
Linux wc 命令可以用来对文本进行统计,包括单词个数、行数、字节数
wc 命令语法

wc [options] [文件名]

options有如下:

选项 含义
-c character,统计字节数
-w word,统计单词数
-l line,统计行数

演示
统计文件 redirect2.txt 中数据行数

wc -l < redirect2.txt

image-20231212143328956

9、shell 好用的工具

9.1 cut

介绍
cut 译为剪切,切割”,是一个强大文本处理工具,它可以将文本按列进行划分的文本处理。cut 命令逐行读入文本,然后按列划分字段并进行提取、输出等操作。

语法

cut [options] filename

options参数说明

选项参数 功能
-f提取范围 列号,获取第几列
-d自定义分隔符 自定义分隔符,默认为制表符。
-c提取范围 以字符为单位进行分割
-b提取范围 以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了-n标志。
-n 与"-b"选项连用,不分割多字节字符;

提取范围说明

提取范围 说明
n- 提取指定第n列或字符或字节后面所有数据
n-m 提取指定第n列或字符或字节到第m列或字符或字节中间的所有数据
-m 提取指定第m列或字符或字节前面所有数据
n1,n2,... 提前指定枚举列的所有数据

示例:

image-20231212143746388

image-20231212143941824

0

评论区