
一、shell1、定义shell是 Unix/Linux 系统中用户与内核之间的接口程序属于命令解释器2、与操作系统的关系shell 充当用户与操作系统之间的桥梁负责解析用户输入的命令并转化为操作系统可理解的指令。它不仅提供了与操作系统交互的界面还支持用户通过脚本自动化执行复杂任务拓展了操作系统的功能与灵活性3、作用解释用户输入的命令并提交给操作系统执行同时提供编程环境4、编程语言分类视角下的 shell编程语言分为编译型和解释型编译型语言如 C/C 需借助编译器如 gcc/g 解释型语言如shell 脚本、python 等。Ubuntu 系统中使用的解释器是 bash 此外还有 ksh、csh 等。在终端输入 shell 命令后由相应解释器如bash 进行解释再将命令执行结果在终端回显二、第一个shell脚本1、shell基本结构文件扩展名通常习惯用.sh作为扩展名不是强制要求。关键在于文件开头的 shebang 行shebang 行一般写成#!/bin/bash这行的作用是指定执行脚本的shell 解释器路径2、注释规范单行注释以# 开头#后面的是注释内容多行注释在 Bash 中可以用EOF 和 EOF包裹起来3、执行方式赋予执行权限后直接运行chmod x xxx.sh ./xxx.shshell解释器运行bash xxx.sh 或者是 sh xxx.sh使用source 执行source xxx.sh或者是 . xxx.sh(.是source的简写)三、shell中的变量变量是存储数据的容器在 shell 脚本中可用来存储各种类型的数据如字符串、数字等1、作用方便在脚本中存储和使用数据避免重复输入内容提升脚本的可维护性与灵活性2、命名规则变量名由字母、数字和下划线组成且不能以数字开头。3、赋值格式变量名 初始值变量名 初始值变量名 初始值变量调用方式使用 $ 符号加上变量名来引用变量的值使用 ${变量名} 形式可避免歧义如str2${str1}world注意事项在shell中定义的变量没有数据类型变量的值都视为字符串如num12345678定义变量时等号两边不允许有空格一般情况下三种定义变量的格式可通用但当变量的初始值包含空格时需用单引号或双引号括起来否则会报错4、变量的类型4.1、系统变量定义由系统自动设置提供有关系统和 shell 环境的信息可在所有脚本中访问示例$HOME(用户主目录)、$USER(当前用户名)等可使用echo $变量名或set 命令查看4.2、用户变量定义由用户在脚本中创建并赋值仅在当前 shell 脚本或会话中有效赋值与使用赋值语法为变量名值引用时使用$变量名或 ${变量名}删除用unset 变量名4.3、环境变量定义可在当前 shell 进程及其子进程中都能访问的变量声明方法使用export 变量名值命令,可让用户自定义变量提升为环境变量在当前 shell 及其子shell中使用4.4、局部变量定义仅在当前 shell 进程或脚本中有效,未export的用户变量默认为隐式局部变量局部变量只在函数内部有效函数执行完毕后局部变量就会被销毁5、特殊变量与位置参数5.1、特殊变量$0表示当前脚本的名称$?表示上一条命令的退出状态码0表示命令执行成功非 0表示命令执行失败5.2、位置参数$1 - $9依次对应执行脚本时传递的第 1 - 9 个参数•10及以上如{10}表示第 10 个参数用于获取序号大于 9 的参数$*包含执行脚本时传递的所有参数(不含脚本文件名)在循环中会将所有参数当作一个整体处理$同样表示执行脚本时传递的所有参数(不含脚本文件名)在循环中会逐个处理每个参数$#表示执行脚本时传递的参数个数(不含脚本文件名)6、修饰变量的关键字6.1、readonly 关键字定义用于修饰变量使其成为只读属性赋值后不可再修改语法readonly 变量名值或先赋值再 readonly 变量名应用场景定义程序中的常量如配置文件路径、版本号保护关键变量不被意外修改注意事项只读变量不能使用 unset 删除重新定义同名变量也无法覆盖只读属性6.2、unset 关键字定义用于取消变量的定义删除后变量引用返回空值语法unset 变量名应用场景释放不再使用的变量节省内存清除包含敏感信息的变量如密码注意事项对 readonly 修饰的变量使用 unset 会报错若变量未定义使用 unset 不会报错6.3、local 关键字定义在函数内部使用用于创建局部变量仅在函数内有效语法function 函数名() { local 变量名值; }应用场景避免函数内变量污染全局作用域保护函数内部的临时数据注意事项函数外使用 local 会报错四、shell中的算术运算方法语法格式示例expr命令expr 操作1 运算符 操作2expr 5 \* 3双括号(...)((变量表示符))((a 53))$((...))$((表达式))echo $((53))五、shell中的数组在 shell 中数组仅支持一维无需预先定义大小元素可为字符串、数字等任意类型元素间用空格分隔索引默认从 0 开始直接赋值法通过括号包裹元素列表赋值语法数组名(元素1 元素2 元素3 ...)逐个赋值法为指定索引的元素赋值语法数组名[索引]元素1、数组元素的访问1.1、访问单个元素用${数组名[索引]}获取指定索引的元素索引可为数字或变量)1.2、访问所有元素${数组名[]}将每个元素作为独立参数适合循环遍历${数组名[*]}将所有元素作为整体字符串元素间用默认空格分隔2、获取数组长度用${#数组名[]}或${#数组名[*]}获取元素个数3、数组的操作3.1、添加元素末尾添加自动在最大索引 1 处添加元素语法数组名(新元素)指定索引添加为指定索引赋值不存在则创建新元素语法数组名[新索引]新元素3.2、修改元素通过索引重新赋值语法数组名[索引]新值3.3、删除元素用unset删除指定索引元素数组变稀疏索引不重排语法unset 数组名[索引]3.4、截取数组获取指定范围元素语法${数组名[]:起始索引:长度}长度可选缺省则到末尾六、read和echo命令1、readread是shell编程里的内置命令用于从标准输入(一般是键盘)或文件中读取数据并赋值给变量语法格式read 选项 变量名1 变量名2 ...说明选项用于控制读取行为变量名用于存储读取的数据若不指定变量名输入会被赋值到环境变量 REPLY(用于临时存储 read 命令的输入结果)注意事项输入分隔读取多个数据时用空格或Tab 键分隔回车键是输入结束标志非数据分隔符变量处理引用变量时用双引号包裹防止空值或特殊字符问题用户直接回车会使变量为空可用参数扩展设默认值格式为${变量名:-默认值}字符转义默认反斜杠(\)是转义符要其作普通字符用-r选项选项规范带参数选项写法和位置要正确多选项顺序不影响功能按习惯规范书写选项功能描述示例-p显示提示信息引导用户输入read -p 输入名字: name -显示 输入姓名-s静态状态输入内容不显示(适用于密码)read -s -p 密码: pass -输入时屏幕无显示-n N读取N个字符后自动结束无需按回车read -n 2 input -输入两个字符后立即结束-t N设置超时时间(秒),超时后退出并返回非零状态码read -t 3 input -3秒无输入则自动结束-a将输入按空格分割为数组存入指定变量read -a arr -arr[0]abc,arr[1]def-r禁止反斜杠转义(将反斜杠视为普通字符)read -r home-d指定行结束符(默认为回车)read -d : input -输入a:时inputa2、echoecho 命令是 shell 脚本中最常用的输出工具用于向终端打印文本或变量值、配合重定向符号如 、将内容写入文件等语法格式echo 选项 字符串/变量注意事项引号区分解析单引号保留字面量双引号解析变量需转义时用 -e变量边界明确变量名后接字符时用${var}避免解析错误转义需显式启用默认不解析 \n、\t需加-e 选项复杂格式用 printfecho格式控制有限复杂场景用 printf选项作用示例-e启用转义字符解析echo -e 第一行\n 第二行-n不换行输出(默认会自动添加换行符)echo -n load...-E禁用转义字符解析(默认行为:部分shell需显示指定)echo -E a\nb → 输出 a\nb(普通字符)转义字符含义示例\n换行无\t制表符(Tab缩进)列1\t列2-列1 列2\\反斜杠\C:\\windows-C:\windows\033[31m红色文本搭配 \033[0m重置\033[31m错误\033[0m → 红色文字七、shell中的条件判断1、if语句在 shell 脚本中条件判断是实现逻辑控制的基础主要通过if语句、test命令[ ]和双括号[[ ]]等结构实现1.1、基本if结构if ((表达式));thenshell语句fi说明当((表达式))的结果为非零值(即条件为真)时执行then后的语句((表达式))是bash特有的算术表达式支持、-、*、/、、等运算符1.2、if-else结构if ((表达式));thenshell语句1elseshell语句2fi说明当表达式为真时执行shell语句1否则执行shell语句21.3、if-elif-else 结构if ((表达式1));thenshell语句1elif ((表达式2));thenshell语句2elif ((表达式3));thenshell语句3...elseshell语句4fi2、test命令在 shell 编程里test 命令的作用是比较数值和字符串、对条件进行测试等常与if语句配合使用2.1、基本格式语法test 表达式或[ 表达式 ]本质调用test命令注意事项使用方括号 [ ] 这种形式时方括号和表达式之间必须有空格在使用变量时建议将变量用双引号引起来这样可以防止变量为空或包含空格时出现问题test 命令的返回状态码为0表示条件成立非0表示条件不成立和其他命令返回值规则是一样2.2、test命令执行逻辑test命令本身是一个elf的可执行程序当执行test命令时后边的数据作为参数传递给test程序中的main函数main函数中有两个参数argc和argv,通过这两个参数可以获得执行test程序时传递的参数因此在表达式中出现参数运算符中括号前后必须添加空格3、数值判断作用用于比较两个整数的大小关系返回状态码0 (真)或1 (假)适用场景脚本中需要比较数字大小的逻辑(如判断年龄、版本号等等)循环条件(如while [ $i -le 10 ])操作符含义等价数字符号-eq等于-ne不等于!-gt大于-lt小于-ge大于等于-le小于等于4、字符串判断作用用于判断字符串的状态是否为空、非空比较字符串间是否相等、大小关系等返回状态码0 (真)或1 (假)适用场景验证用户输入是否合规如用户名、密码是否为空是否符合格式要求)文本处理中筛选、过滤特定字符串内容如在日志文件中查找特定关键词)程序逻辑中根据字符串状态决定执行分支如在 if - then - else 结构中判断5、逻辑判断作用逻辑判断用于组合多个条件表达式形成更复杂的判断适用场景多条件筛选同时满足多个条件时执行操作如年龄 18 且分数≥60容错处理多个条件中只要满足一个即可执行操作如文件存在或目录可写权限验证验证用户是否属于特定角色或组如用户是 root 或管理员组操作符含义示例 假设a10,b20-a逻辑与同时都满足[ $a -gt 5 -a $b -lt 30 ]真-o逻辑或满足一个即可[ $a -eq 0 -o $b -eq 20 ] (真)逻辑非取反[ ! -d $dir ] -若目录不存在则为真6、文件判断作用用于检查文件或目录的状态是否存在、类型、权限等返回状态码0 (真)或1 (假)适用场景脚本初始化与依赖检查在执行核心逻辑前确保必要的文件或目录存在且状态正确文件操作前的安全检查避免误操作导致数据丢失或权限问题条件性执行任务根据文件状态决定执行不同的分支权限管理与安全控制限制脚本只在特定权限下执行注意事项始终用双引号包裹变量防止路径或变量值包含空格、通配符时被shell错误解析结合逻辑操作符处理多条件场景单一条件无法满足复杂需求需组合判断(如文件存在且可写)注意权限和文件类型的差异不同操作需要不同的文件类型和权限混淆会导致意外结果操作符作用描述示例file“test.txt”-e FILE检查文件/目录是否存在-e $file -存在为真-f FILE检查是否为普通文件-f $file -是普通文件-d FILE检查是否为目录-d /etc -是目录则为真-r FILE检查当前用户是否有可读权限-r $file -可读则为真-w FILE检查当前用户是否有可写权限-r $file -可写则为真-x FILE检查当前用户是否有可执行权限-x $script.sh -可执行则为真-s FILE检查文件是否存在且非空(文件大小0)-s $log.log -非空为真-L FILE检查是否为符号链接(不验证是否有效)-L $link -是则为真FILE1 -nt FILE2检查FILE1是否比FILE2新$new.txt -nt $old.txt -新则真FILE1 -ot FILE2检查FILE1是否比FILE2旧$old.txt -ot $new.txt -旧则真7、[[ ]]的使用在 shell 编程中[[ ... ]] 是 Bash 提供的高级条件测试语法比传统的 [ ... ] 更强大、更灵活7.1、基本语法if [[ 条件表达式1 ]];thenshell语句1elif [[ 条件表达式2 ]];thenshell语句2elseshell语句3fi主要优势无需转义特殊字符在 [[ ... ]] 中需要转义的特殊符号如 、、!等可直接使用无需添加反斜杠 \ 或引号包裹支持短路求值提升执行效率逻辑操作符逻辑与和||逻辑或具备短路特性。当 左侧条件为假时右侧条件不再执行当|| 左侧条件为真时右侧条件不再执行语法更友好贴近自然逻辑[[ ... ]] 的条件表达式结构更接近自然语言直接使用 /||降低学习成本安全处理未定义变量若变量未定义[[ ... ]] 会将其视为空字符串避免 [ ... ] 可能触发的语法错误8、case...in语句在 shell 编程中case...in 语句是一种多路分支结构用于根据不同的条件执行相应的代码块。它类似于其他编程语言中的 switch - case 语句能让代码在面对多种情况时清晰、简洁地进行逻辑处理8.1、基本语法case变量in模式1)命令序列1;;模式2)命令序列2;;*)默认命令序列;;esac8.2、说明case 关键字标志着 case...in 语句的开始后面紧跟要进行条件判断的变量in 关键字用于分隔变量和后续的模式匹配部分模式用于与变量的值进行匹配可以是字符串、数值也支持通配符如*匹配任意字符序列?匹配单个字符))表示模式的结束其后紧跟该模式匹配时要执行的命令序列命令序列是在模式匹配成功后执行的具体操作;;用于结束当前模式对应的命令序列起到类似于其他语言中break 的作用防止执行完当前命令序列后继续执行下一个模式的命令*这是默认模式当变量的值与前面定义的所有模式都不匹配时就会执行该模式下的命令序列esac标志着case...in 语句的结束是case 反过来拼写8.3、适用场景交互式脚本如命令行工具、配置脚本等用于处理用户输入的不同选项文件类型或名称处理根据文件的扩展名或名称特征执行不同的操作如文件分类、备份策略选择等系统状态检查脚本根据不同的系统状态标识如服务状态标识执行相应的管理操作9、select...in语句select...in是 shell 脚本中用于创建交互式菜单的专用命令主要用于引导用户通过键盘输入选择预设选项。它会自动为每个选项生成编号从 1 开始用户输入对应数字即可触发相应操作适合需要频繁与用户交互的场景如脚本配置、功能选择等9.1、基本语法select 变量名 in 选项1 选项2 选项3...do命令序列[break] # 可选用于退出循环done9.2、说明select 关键字标志着交互式菜单的开始后面紧跟用于存储用户选择的变量名in 关键字分隔变量名和选项列表选项列表用空格分隔的多个选项支持字符串、变量等每个选项会自动对应一个编号do...done循环体用户输入选择后会执行循环体内的命令序列。若未匹配到有效选项会重新显示菜单提示9.3、适用场景交互式脚本配置引导用户完成系统配置菜单选数字触发功能提升易用性功能选择菜单为脚本多模块生成选择菜单输数字切换功能免记复杂参数循环交互式操作适用于重复任务菜单循环显示无需重启脚本简化用户输入逻辑替代手动输入自动编号菜单降低非技术用户操作成本八、shell中的循环结构1、for循环适用于已知要遍历的元素集合如数组、列表或明确循环次数的场景通过依次迭代集合元素或按指定数字范围来执行循环体基本语法遍历列表:for变量in 列表或数组元素;do命令1命令2...done数字范围循环:for((初始值; 条件; 增量或减量));do命令1命令2...done优势语法简洁直观在处理固定集合或确定次数循环时代码逻辑清晰易于理解和编写应用场景遍历目录下文件、对数组元素逐一操作、按指定次数执行任务等2、while循环根据条件判断结果决定是否执行循环体只要条件为真就持续循环直到条件为假时结束适用于条件动态变化或不确定循环次数的情况基本语法while条件判断;do命令1命令2...done说明在这个结构中条件判断可以是各种各样的测试像数值比较、字符串比较、文件状态检测等只要条件判断的结果为真返回状态码0循环体就会一直执行一旦条件判断结果为假返回状态码非 0循环就会终止优势灵活性高能处理各种复杂的条件判断场景像等待文件出现、监控系统状态变化等应用场景等待特定条件满足如等待某个进程启动、动态读取输入如交互式脚本等待用户输入符合条件的值、持续监控资源状态如磁盘空间、内存使用情况)等3、until循环与while循环相反until循环基于条件判断结果决定是否执行循环体不过是条件为假时持续循环一旦条件变为真就结束循环适用于需要等待某个条件达成的场景3.1、基本语法until条件判断;do命令1命令2...done3.2、执行逻辑条件判断可以是数值比较、字符串比较、文件状态检测等各种测试只要条件判断结果为假返回状态码非 0循环体就会一直执行当条件判断结果变为真返回状态码 0时循环终止优势在需要等待特定条件从假变为真的场景中逻辑表达更自然清晰避免在while循环中使用双重否定条件例如不必写while [ ! -f file.txt ]而是直接用until [ -f file.txt ])应用场景等待特定条件满足如等待文件出现、进程启动完成等)重试操作直到成功如网络连接、命令执行成功需要确保循环体至少执行一次的情况类似其他语言中的do-while循环4、break和continue4.1、break 关键字功能break的作用是强制终止当前所在的循环无论循环条件是否仍然满足程序都会立即跳出该循环然后继续执行循环体后面的代码使用场景常用于在满足特定条件时提前结束整个循环比如在找到目标值后停止搜索、在用户输入退出指令时终止程序等情况4.2、continue 关键字功能continue的作用是跳过当前这一轮循环体中剩余的代码直接开始下一轮循环程序会忽略continue后面的语句回到循环的起始处重新判断循环条件若条件满足则继续执行下一轮循环使用场景常用于过滤掉某些不需要处理的情况比如跳过不符合条件的数据、忽略错误输入等九、shell中的函数1、函数定义与调用在 shell 编程中函数是一种将多次使用的代码块封装起来的机制它可以提高代码的复用性和可维护性基础语法标准格式function 函数名() {命令1命令2...[return 返回值] # 可选返回值范围0-255}简化格式函数名(){命令1命令2...}函数调用直接使用函数名即可调用若函数需要参数直接跟在函数名后面参数之间用空格分隔2、函数参数参数传递在 shell 中函数通过位置参数接收传递给它的参数$1, $2, ..., $n表示第 1 到第 n 个参数$0表示脚本本身的名称在函数内部使用时它仍然表示脚本名而不是函数名$#表示参数的个数$或$*表示所有参数$将参数视为独立的个体$*将所有参数视为一个整体3、函数返回值3.1、通过return语句返回状态码功能设置函数的退出状态码范围 0-255用于表示函数执行的成功0或失败非 0特点状态码可通过$?变量获取但仅能是整数return语句会立即终止函数执行类似exit但仅作用于函数3.2、通过echo输出返回结果功能将计算结果通过标准输出返回调用者可通过命令替换捕获特点可返回任意文本内容不限于数字需避免在函数中输出调试信息以免干扰返回值4、函数输出捕获函数输出捕获则是获取函数实际计算结果如字符串、数值等return 语句仅用于返回状态码设置函数退出状态码需结合$?获取限制仅能返回整数0-255主要用于表示执行状态而非数据结果使用 echo 输出 命令替换捕获通过echo将结果输出到标准输出再用$(...)或反引号捕获总结shell是命令解释器兼脚本语言linux下以Bash为主脚本用# !/bin/bash开头。重点掌握变量、条件、循环、函数这几大块本质就是把一条条命令用控制流串起来自动化重复任务一定要多写多练。