注意:
- 赋值规则 :等号
=前后无空格 (name=John✔️,name = John❌); - 引号规则 :
- 双引号
":保留变量值(echo "name=$name"→name=John); - 单引号
':原样输出(echo 'name=$name'→name=$name);
- 双引号
一、变量规格(基本变量)
-
直接定义
- 语法:
变量名="值"(等号两侧无空格) - 示例:
name="john" - 说明:Shell 默认变量为字符串类型
- 语法:
-
只读变量
- 关键字:
readonly - 语法:
readonly 变量名=值或变量名=值; readonly 变量名 - 特点:赋值后不可修改、不可删除
- 关键字:
-
删除变量
- 关键字:
unset - 语法:
unset 变量名 - 注意:只读变量无法被
unset删除
- 关键字:
二、变量类型
1. 整数变量
- 声明关键字:
declare -i - 作用:强制变量为整数类型,支持直接算术运算
bash
declare -i num=9
num=num+1
echo "值为:$num" #值为:10
2. 数组变量(基本数据 / 普通数组)
- 定义语法:
数组名=(值1 值2 值3 ...) - 特点:使用数字下标(从 0 开始)访问元素
bash
arr=(aasdasd b c)
echo ${arr[0]} # 取第1个值:a
echo ${arr[@]} # 取所有值:a b c
echo ${!arr[@]} # 取所有下标:0 1 2
echo ${#arr[@]} # 取长度:3
echo ${#arr[0]} #获取数组指定元素的长度:7
3. 关联数组(键值关联)
- 声明关键字:
declare -A - 作用:使用字符串键(key) 索引值(value),实现键值对存储
bash
declare -A user_info
user_info["name"]="John"
user_info["age"]=30
user_info["city"]="New York"
# 1. ${!user_info[@]} → 获取所有键
echo "所有键:${!user_info[@]}" # 输出:所有键:name age city
# 2. ${user_info[@]} → 获取所有值(无!)
echo "所有值:${user_info[@]}" # 输出:所有值:John 30 New York
4、环境变量
export 变量名=值全局生效,子进程可继承配置系统环境(如 PATH)
5、只读变量
readonly 变量名 / declare -r赋值后不可修改 / 删除固定配置(如版本号)
6、特殊变量
| 变量 | 核心含义 | 示例场景 | 示例输出 / 说明 |
|---|---|---|---|
$0 |
当前执行的脚本名(含路径 / 纯文件名) | 执行 ./test.sh |
$0 = ./test.sh(或 test.sh) |
$1-$9 |
命令行传入的第 1~9 个参数 | 执行 ./test.sh 10 20 30 |
$1=10、$2=20、$3=30 |
${10} |
第 10+ 个参数(需加花括号) | 执行 ./test.sh 1 2 ... 10 |
${10}=10(直接写 $10 会识别为 $1+0) |
$# |
命令行传入的参数总个数 | 执行 ./test.sh 10 20 |
$#=2 |
$? |
上一条命令的退出状态码(0 = 成功,非 0 = 失败) | 执行 ls && echo $? 执行 ls xxx && echo $? |
0(ls 成功)2(ls 失败) |
$$ |
当前脚本的 PID(进程号) | 任意脚本中执行 echo $$ |
输出一串数字(如 12345),唯一标识当前脚本进程 |
$* |
所有参数(视为一个整体) | 执行 ./test.sh a b c |
"$*" = "a b c" |
$@ |
所有参数(视为独立个体) | 执行 ./test.sh a b c |
"$@" = "a" "b" "c" |
三、基本运算符
-
算数运算符
- 一般使用expr,但注意,表达式和运算符之间要有空格隔开,且整个式子必须用反引号包含起来(esc键下方)
basha=1 b=2 num=`expr $a \* $b` #+、-、/、%、=用法一致,但*需要添加\,转义 echo $num # 2 #==判断两数是否相等 if [ $a == $b ] then echo "a 等于 b" fi #判断两个数是否不相等 if [ $a != $b ] then echo "a 等于 b" fi -
关系运算符
*运算符 说明 举例 -eq 检测两个数是否相等,相等返回 true。 [ a -eq b ] 返回 false。 -ne 检测两个数是否不相等,不相等返回 true。 [ a -ne b ] 返回 true。 -gt 检测左边的数是否大于右边的,如果是,则返回 true。> [ a -gt b ] 返回 false。 -lt 检测左边的数是否小于右边的,如果是,则返回 true。< [ a -lt b ] 返回 true。 -
布尔运算符
*运算符 说明 举例 ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。 -o 或运算,有一个表达式为 true 则返回 true。 [ a -lt 20 -o b -gt 100 ] 返回 true。 -a 与运算,两个表达式都为 true 才返回 true。 [ a -lt 20 -a b -gt 100 ] 返回 false。 运算符 说明 举例 && 逻辑的 AND [[ a -lt 100 \&\& b -gt 100 ]] 返回 false || 逻辑的 OR [[ a -lt 100 || b -gt 100 ]] 返回 true -
字符串运算符
*运算符 说明 举例 = 检测两个字符串是否相等,相等返回 true。 [ a = b ] 返回 false。 != 检测两个字符串是否不相等,不相等返回 true。 [ a != b ] 返回 true。 -z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。 -n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n "$a" ] 返回 true。 $ 检测字符串是否不为空,不为空返回 true。 [ $a ] 返回 true。 bash获取长度:${#str} str="hello" echo ${#str} # 输出 5 字符串截取:${str:起始位置:长度} str="hello" echo ${str:1:3} # 输出 ell 字符串替换:${str/旧字符串/新字符串} str="hello" echo ${str/ll/xx} # 输出 hexxo -
文件测试运算符(按使用频率排序)
*运算符 核心含义 示例(判断成立则返回 true) -f检测是否为普通文件(非目录 / 设备) [ -f /etc/passwd ](passwd 是普通文件)-d检测是否为目录 [ -d /tmp ](tmp 是目录)-e检测文件 / 目录是否存在(通用) [ -e /root ](root 目录存在)-r检测当前用户是否有读权限 [ -r /etc/shadow ](普通用户无读权限)-w检测当前用户是否有写权限 [ -w /tmp/test.txt ](tmp 下文件可写)-x检测当前用户是否有执行权限 [ -x /bin/ls ](ls 命令有执行权限)-s检测文件是否非空(大小 > 0) [ -s /var/log/messages ](日志文件非空)-L检测是否为符号链接(软链接) [ -L /etc/rc.local ](rc.local 是软链接)-b检测是否为块设备文件(磁盘 / 分区) [ -b /dev/sda ](sda 是块设备)-c检测是否为字符设备文件(终端 / 串口) [ -c /dev/tty1 ](tty1 是字符设备)-S检测是否为套接字文件(socket) [ -S /var/run/mysqld/mysqld.sock ]-nt检测文件 A是否比文件 B 新(修改时间) [ fileA -nt fileB ]-ot检测文件 A是否比文件 B 旧(修改时间) [ fileA -ot fileB ]-ef检测两个文件是否为同一个文件(硬链接 / 相同 inode) [ file1 -ef file2 ]
四、输出
1、echo
2、printf(可以多试试,这个挺有趣的)
bash
printf "%d %o %x\n" 52 52 52 #十进制、八进制、十六进制
printf "%f %e\n" 2.43 2.444543534#浮点数、科学计数发
printf "%s\n" "john"#字符串
printf "%c\n" "aaa"#字符,只会输出a