Shell脚本入门:从变量到函数全解析 第一个shell脚本#! 是一个约定的标记它告诉系统这个脚本需要什么解释器来执行即使用哪一种 Shell常用/bin/bash解释器运行 Shell 脚本有两种方法1 使用bash工具执行脚本. test.shsh test.sh2 让文件自己运行需要添加可执行权限chmod x test.sh./test.shShell 变量在 Shell 编程中变量是用于存储数据值的名称。your_namecrazy变量值里有空格、特殊符号必须用引号包起来变量名的命名须遵循如下规则只包含字母、数字和下划线不能以数字开头避免使用 Shell 关键字使用大写字母表示常量避免使用特殊符号避免使用空格单引号和双引号的区别单引号是纯字符串什么都不解析双引号会解析变量、$、转义字符。花括号是为了帮助解释器识别变量的边界[rootweb01 4.13]# mynamejis [rootweb01 4.13]# echo $myname jis [rootweb01 4.13]# echo $mynamess [rootweb01 4.13]# echo ${myname}ss jisss只读变量[rootweb01 4.13]# myurl123.com [rootweb01 4.13]# readonly myurl [rootweb01 4.13]# myurl321.com bash: myurl: readonly variable怎么取消这个只读变量在当前这个终端里无法取消、无法修改。 只有 2 条路方法 1退出当前终端重新连接 关掉 SSH重新登录变量就没了。 方法 2在当前 shell 里启动一个新子 shell删除变量[rootweb01 4.13]# myurl213.com [rootweb01 4.13]# echo $myurl 213.com [rootweb01 4.13]# unset myurl [rootweb01 4.13]# echo $myurlShell 变量 5 大类型1字符串变量在 Shell中变量通常被视为字符串。你可以使用单引号 或双引号 来定义字符串2. 整数变量需要用declare -i声明只能存数字不能存字母declare -i num100 num200 # 正常 numabc # 报错或变成 03. 数组变量一次存多个值 普通数组下标 0、1、2…arr(aa bb cc) echo ${arr[0]} # 输出 aa关联数组键值对类似字典关联数组用「名字 / 字符串」找值# 声明关联数组 declare -A person # 赋值key → value person[name]老李 person[age]30 person[city]南京 # 取值 echo ${person[name]} echo ${person[age]}4. 环境变量系统 / 用户自带全局生效作用配置系统环境、路径等Linux 最核心的环境变量echo $HOME # 当前用户的家目录 echo $PWD # 当前所在目录 echo $USER # 当前用户名 echo $UID # 当前用户IDroot是0 echo $SHELL # 当前用的shell echo $LANG # 语言/编码 echo $PS1 # 命令行提示符样式 echo $HOSTNAME # 主机名 echo $OLDPWD # 上一次所在目录5. 特殊变量系统自带有特殊用途这些是 Shell 内置的最常用$0 # 脚本名字 $1 # 第一个参数 $2 # 第二个参数 $# # 参数个数 $? # 上一条命令是否成功0成功非0失败 $$ # 当前进程ID拼接字符串[rootweb01 4.13]# mynamelaoli [rootweb01 4.13]# echo hello,$myname hello,laoli [rootweb01 4.13]# echo hello,${myname}123 hello,laoli123 单引号不能解析变量 [rootweb01 4.13]# echo hello,${myname}123 hello,${myname}123获取字符串长度[rootweb01 4.13]# stringabcd [rootweb01 4.13]# echo $string abcd [rootweb01 4.13]# echo ${#string} 4提取子字符串[rootweb01 4.13]# echo ${string:1:3} bcd [rootweb01 4.13]# echo ${string:1:2} bc查找子字符串expr index 字符串 ab 在字符串里找 a 或 b 谁先出现就返回谁的位置 位置从1 开始数[rootweb01 4.13]# stringhello nishi world [rootweb01 4.13]# echo expr index $string io expr: syntax error 只要变量里 有空格、有特殊符号 [rootweb01 4.13]# echo expr index $string io 5Shell 数组基础特性1. Bash Shell 仅支持一维数组不支持多维数组2. 初始化时无需指定数组大小3. 数组下标从 0 开始4. 数组用小括号 () 表示元素之间用空格分隔定义数组数组名(值1 值2 ... 值n)array_name(value0 value1 value2 value3)array_name(value0value1value2value3)还可以单独定义数组的各个分量array_name[0]value0array_name[1]value1array_name[n]valuen可以不使用连续的下标而且下标的范围没有限制。读取数组读取数组元素值的一般格式是${数组名[下标]}valuen${array_name[n]}使用 或者 * 可以获取数组中的所有元素例如echo ${array_name[]} echo ${array_name[*]}使用#号可以获取元素个数[rootweb01 4.13]# echo ${#arr_test[*]} 4 [rootweb01 4.13]# echo ${#arr_test[]} 4关联数组键值对数组1. 声明关联数组必须使用declare -A声明declare -A array_name2赋值site[google]www.google.com site[runoob]www.runoob.com3访问 / 取值echo ${site[runoob]} echo ${site[google]}4. 获取关联数组所有键 在数组前加 !${!array_name[*]} ${!array_name[]}获取数组的长度获取数组长度的方法与获取字符串长度的方法相同# 取得数组元素的个数 length${#array_name[]} # 或者 length${#array_name[*]} # 取得数组单个元素的长度 length${#array_name[n]}用法语法定义普通数组arr(v1 v2 v3)下标赋值arr[0]v0取单个元素${arr[0]}取全部元素、{arr[*]}声明关联数组declare -A arr取所有键${!arr[]}取数组长度${#arr[]}shell注释方式1#开头注释2多行注释 使用 Here 文档:EOF 注释内容... 注释内容... 注释内容... EOF3直接使用 : 号我们也可以使用了冒号 : 命令并用单引号 将多行内容括起来。由于冒号是一个空命令这些内容不会被执行。格式为: 空格 单引号。: 这是注释的部分。 可以有多行内容。 shell传参$1、$2 等来引用传递给脚本的参数其中 $1 表示第一个参数$2 表示第二个参数依此类推。$0为执行的文件名echo Shell 传递参数实例; echo 执行的文件名$0; echo 第一个参数为$1; echo 第二个参数为$2; echo 第三个参数为$3; $ ./test.sh 1 2 3 Shell 传递参数实例 执行的文件名./test.sh 第一个参数为1 第二个参数为2 第三个参数为3处理参数的特殊字符$0 当前脚本的文件名$1 - $9 第1到第9个参数$* 所有参数当成一整串$ 所有参数分开独立$# 参数总个数$$ 当前进程的 PID$? 上一条命令的退出状态0成功非0失败#/bin/bash echo 脚本名$0 echo 第1个参数$1 echo 第2个参数$2 echo 总参数个数$# echo 所有参数$ echo 上一条命令结果$?read -p 是什么•read读取用户输入-pprompt提示信息•作用先显示一句话再等待你输入内容标准写法read -p 请输入内容 变量名例子#!/bin/bash read -p 请输入你的名字 name read -p 请输入你的年龄 age echo 你好 $name你今年 $age 岁Shell 基本运算符1算术运算符运算符说明举例结果加法expr $a $b30-减法expr $a - $b-10*乘法必须转义expr $a \* $b200/除法expr $b / $a2%取余expr $b % $a0赋值a$ba 变量值变为 20相等[ $a $b ]假!不相等[ $a ! $b ]真valexpr $a $b2关系运算符运算符说明举例结果-eq检测是否相等[ $a -eq $b ]假-ne检测是否不相等[ $a -ne $b ]真-gt检测左边是否大于右边[ $a -gt $b ]假-lt检测左边是否小于右边[ $a -lt $b ]真-ge检测左边是否大于等于右边[ $a -ge $b ]假-le检测左边是否小于等于右边[ $a -le $b ]真if [ $a -lt $b ] then echo a 小于 b fi3布尔运算符运算符说明举例结果!非运算[ ! false ]真-o或运算一个为真则真[ $a -lt 20 -o $b -gt 100 ]真-a与运算都为真才真[ $a -lt 20 -a $b -gt 100 ]假4逻辑运算符运算符说明举例逻辑 AND||逻辑 OR5字符串运算符运算符说明举例结果检测字符串是否相等[ $a $b ]假!检测字符串是否不相等[ $a ! $b ]真-z检测字符串长度是否为 0[ -z $a ]假-n检测字符串长度是否不为 0[ -n $a ]真$检测字符串是否为空[ $a ]真6文件测试运算符操作符说明-f file检测文件是否是普通文件-r file检测文件是否可读-w file检测文件是否可写-x file检测文件是否可执行-s file检测文件是否为空大小 0-e file检测文件包括目录是否存在-L file检测文件是否是符号链接file/test.sh if [ -r $file ] then echo 文件可读 fi7自增与自减Shell 中没有 i i-- 直接语法常用写法1. let i2. let i--3. ((i))4. ((i--))5. i$((i1))6. i$(expr $i 1)Shell 数学运算4 种主要方法可以概括如下$((表达式))最推荐的标准算术扩展语法简洁功能强大支持各种 C 风格运算符。expr 表达式传统外部命令需注意操作符和空格现已较少使用。let 表达式Shell 内置命令类似 C 语言语法但灵活性不如 $((...))。$(())常与 $((...)) 结合用于赋值或嵌套是算术扩展的一种应用形式。总的来说$((...)) 是首选方式。shell流程控制条件判断1. 单分支 ifif 条件 then 命令 fi2. 双分支 if elseif 条件 then 命令 else 命令 fi3. 多分支 if elif elseif 条件1 then 命令 elif 条件2 then 命令 else 命令 fi4. 两种判断写法[ ]格式用-eq()-gt()-lt()(( ))格式直接用 循环结构1. for 循环遍历 → 执行作用挨个处理列表里的内容for 变量 in 列表 do 命令 done2. while 循环条件为真 → 执行作用条件满足就一直跑while 条件 do 命令 done3. until 循环条件为假 → 执行作用和 while 相反条件成立就停止until 条件 do 命令 done多分支匹配类似 switch匹配模式case...esaccase 变量 in 模式1) 命令 ;; 模式2) 命令 ;; *) 默认命令 ;; esac;; 执行完跳出*) 都不匹配时走这里循环控制跳出逻辑break跳出整个循环结束循环continue跳过本次循环直接进入下一次Shell 函数一、函数定义# 写法1最常用、推荐 函数名() { 代码内容 } # 写法2带 function function 函数名() { 代码内容 }必须先定义后调用定义时必须加 ()调用时不能加 ()二、函数返回值1. return 只能返回 0~255 的整数2. 用 $? 获取上一条命令 / 函数的返回值三、函数参数函数内部通过$n获取参数$1→ 第 1 个参数$2→ 第 2 个参数${10}→ 第 10 个参数≥10 必须加 {}特殊参数变量$#→ 参数个数$*→ 所有参数字符串$→ 所有参数分开$?→ 上一条命令退出码0 成功非 0 失败四、函数调用# 无参调用 函数名 myping # 有参调用 函数名 参数1 参数2 参数3 myping 192.168.74.$iShell 文件包含一、核心作用在一个 Shell 脚本里引入并执行另一个脚本直接使用它的变量、函数实现代码复用。二、两种语法完全等价. 文件名 # 点 空格 文件名 source 文件名 # 最常用、最易懂包含后被引入文件的变量、函数可以直接用路径写对当前目录用 ./文件名三、最简单示例test1.sh定义变量urlhttp://www.runoob.comtest2.sh引入并使用#!/bin/bash source ./test1.sh echo 地址$url补充知识点