1 变量定义(与java类似)
示例:your_name="runoob"
变量定义的规则(比较多,这里我只列出来跟java不同的)
2 变量使用
在变量名前面加美元符号即可,例如:
your_name="runoob"
echo $your_name
echo ${your_name}
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,避免把别的字符串当做变量名的一部分,比如:
echo "I am good at ${skill}Script",如果没有括号就会去读取skillScript这个值为空的变量。
变量还能重新赋值(与java类似,跳过)
3 只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。(与java的final类似,不过它是命令,不会和变量放同一行)
示例:
脚本内容如下

运行结果

4 删除变量
语法是:unset variable_name,不能删除只读(readonly)变量,这里我觉得和java很不一样,从这里我大致发觉到了shell脚本的复杂度。
5 变量的类型
它的类型有很多种,主要包括
5.1 字符串变量
可以使用双引号”或者单引号’定义。
如果是单引号,那内部不能单独出现变量(可以用一对单引号用作字符串拼接),不能出现单个单引号,只能成对出现,转义也不行。
如果是双引号,内部既可以出现变量,也可以使用转义字符,比如:


字符串之间可以进行拼接。
测试脚本如下:

结果:

这里需要注意的是,两个变量的拼接只能用双引号不能用单引号。
获取字符串长度命令:${#变量名}
string="abcd"
echo ${#string} #结果为4
字符串截取命令:${变量名:m:n}从m位置开始(包含m),取n个字符。
字符串查找:这里菜鸟教程的做法是这样的,使用expr index命令:
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
我觉得这不算字符串查找,而且查找另一个字符串中的单个字符毫无意义。我去学了另一种真正的子字符串查找的做法:

结果:

命令解读:出现在echo后的awk命令,用于处理整行或者整个文件的数据。
单引号是具体的处理方式,比如这里打印出”bbb”字符串出现的位置(起点是1)。
参数$0表示一整行字符串。还有$1、$2等,代表对字符串按照空格拆分后的处理结果,$1代表分割后第一个字符串。如果有多行文本,这里就是每一行第一个字符串。
如果文件有多行,通过NR指定行号,比如awk ‘NR==2 print($0)’ data.txt。
5.2 整数变量
可以使用declare -i 或 typeset 命令来声明整数变量。如果把非整数赋值给该变量,shell会尝试将其转为整数(这里测试发现如果转换失败会变成0,比如传个a进去)。
脚本示例:

结果:

5.3 数组变量(不支持多维数组)
索引数组:
带初始值的数组:
my_array=(1 2 3 4 5)
手动赋值的数组:
declare -a my_array
my_array[0]=”0”
关联数组(类似于map)
需配合declare命令,加上参数-A定义:
declare -A associative_array
associative_array["name"]="John"
associative_array["age"]=30
获取关联数组的所有键:${!associative_array[@]}

输出是name date year
使用@或*可以获取数组的所有元素:

输出是1 2 3 4。
获取数组长度:${#string[@]}
5.4 环境变量
由操作系统或用户设置的特殊变量,用于配置 Shell 的行为和影响其执行环境
例如PATH代表系统搜索可执行命令的路径

也就是你输入一个命令之后,它默认去哪里找,就比如最简单的echo命令就在usr/bin下:

5.5 特殊变量
有一些特殊变量在 Shell 中具有特殊含义,例如 $0 表示脚本的名称,$1, $2, 等表示脚本的参数。$#表示传递给脚本的参数数量,$? 表示上一个命令的退出状态(0表示成功,非0表示失败)等。
结果如下:



