Shell脚本入门教程-变量篇

734 阅读1分钟

目录

  1. 基础命令
  1. 变量
  1. 创建并运行脚本
  1. 条件
  1. 循环
  1. 函数
  1. 其他(read、mktemp、trap)

变量

环境变量

  1. 命令env打印系统的环境变量
$ env

用户变量

  1. 命令set打印系统的用户变量
$ set
  1. 命令set name value或直接使用name=value可以设置环境变量,该命令中,等号左边是变量名,等号右边是变量。
$ a="z"                     # 变量 a 赋值为字符串 z
$ b="a string"              # 变量值包含空格,就必须放在引号里面
$ c="a string and $b"       # 变量值可以引用其他变量的值
$ d="\t\ta string\n"        # 变量值可以使用转义字符
$ e="$(ls -l foo.txt)"      # 变量值可以是命令的执行结果
$ f="$((5 * 7))"            # 变量值可以是数学运算的结果

注意,等号两边不能有空格,如果变量的值包含空格,则必须将值放在引号中。

  1. 命令unset name或直接使用name=""可以删除用户变量
$ a="z"
$ echo "${a}"
$ unset a
$ echo "${a}"
  1. 命令export name=value可以设置能够继承给子Shell的环境变量。

注意:通过set创建的环境变量仅可用于当前Shell,子Shell默认读取不到父Shell定义的变量。

$ export foo=bar
# 新建子Shell
$ bash
# 读取 $foo
$ echo $foo
bar
# 修改继承的变量
$ foo=baz
# 退出子 Shell
$ exit
# 读取 $foo
$ echo $foo
bar

特殊变量

  1. $0为当前Shell的名称(在命令行直接执行时)或者脚本名(在脚本中执行时)。
$ echo "${0}"
-bash
  1. $?为上一条命令的退出码,用来判断上一条命令是否执行成功。若为零,则表示上一条命令执行成功;若为非零,则表示上一条命令执行失败。
# 浏览一个不存在的目录
$ ls notexistsfile
ls: cannot access notexistsfile: No Such file or directory
$ echo "{$?}"
2
​
# 浏览当前目录,肯定存在
$ ls . 
xxxxxx xxxx xxxx xxx
$ echo "{$?}"
0

字符串处理

在脚本编写中,常常会遇到字符串处理的需求,比如说在路径处理的时候,下面是一些常用的字符串处理操作。

  1. 获得字符串长度
# 获得字符串长度
$ varname="Good Morning"
$ echo "${#varname}"
  1. 获得子字符串
# 获得子字符串,从第0个位置开始,长度为2的子字符串
$ varname="Good Morning"
$ echo "${varname:0:2}"
  1. 大小写转换
# 转为大写
$ varname="Good Morning"
echo "${varname^^}"
GOOD MORNING!
​
# 转为小写
${varname,,}
echo "${varname,,}"
good morning!
  1. 搜索与替换
  • 使用${variable#pattern}进行最短匹配并返回剩余部分,如果匹配不成功,则返回原始字符串。
  • 使用${variable##pattern}进行最长匹配(贪婪匹配) 并返回剩余部分,如果匹配不成功,则返回原始字符串。
$ txtPath="/home/yanx/pink.txt"$ echo "${txtPath#/*/}"
yanx/pink.txt
​
$ echo "${txtPath##/*/}"
pink.txt
  • 使用${variable/pattern/string}进行最长匹配(贪婪匹配) ,并将首个匹配部分替换为string,然后返回,如果匹配不成功,则返回原始字符串。
  • 使用${variable//pattern/string}进行最长匹配(贪婪匹配) ,并将所有匹配部分替换为string,然后返回,如果匹配不成功,则返回原始字符串。
$ txtPath="/home/yanx/yanx.txt"
​
$ echo "${txtPath/yanx/yanX}"
/home/yanX/yanx.txt
​
$ echo "${txtPath//yanx/yanX}"
/home/yanX/yanX.txt

匹配模式不完全遵循正则表达式,仅可以使用*?[]等通配符。

表达式处理

# 运算表达式
$ foo="$((2*2))";# 布尔表达式
$ foo="$((3 > 2))"

数组处理

  1. 创建数组

数组可以采用逐个赋值的方法创建。

ARRAY[INDEX]=value

上面语法中,ARRAY是数组的名字,可以是任意合法的变量名。INDEX是一个大于或等于零的整数,也可以是算术表达式。注意数组第一个元素的下标是0, 而不是1。

以下是三种创建数组的方式:

ARRAY[0]=value1
ARRAY[1]=value2
ARRAY[2]=value3
...
ARRAY[N]=valueN
​
ARRAY=(value1 value2 ... valueN)
​
# 等同于ARRAY=(
  value1
  value2
  value3
)
  1. 存储数据

数组存在的目的就是存入有效的数据,存入数据的方式一般分为两种,一种是存入用户输入的数据,一种存入命令执行的结果。

存入用户数据的数据可以使用以下命令:

read -a dices
for dice in ${dices[@]};
do
    echo ${dice}
done

读取命令执行的结果可以使用以下命令:

dices=$(cat ~/.bash_profile)
for dice in ${dices[@]};
do
    echo ${dice}
done

注意:循环操作可以参考后续章节[循环结构],数组循环时,如果单纯使用dices,则只返回第一条数据,只有使用{dices},则只返回第一条数据,只有使用{dices[@]}才会返回所有数据。

  1. 读取数据

循环读取在上面的例子中已经有了,下面的例子是单个读取的例子:

$ dices=(1,2,3,4,5)
$ echo ${array[0]}
1
  1. 数组操作
  • 获得长度
${#array[*]}
${#array[@]}
  • 获得存在有效值的索引
array[0]=0
array[2]=2
for item in ${!array[@]}
do
    echo ${item}
done
  • 删除数组元素和删除数组
array[0]=0
array[1]=1
array[2]=2

# 打印全数组内容
for item in ${array[@]}
do
    echo ${item}
done

# 删除数组索引位置1的元素,打印内容为1,2
unset array[1]
for item in ${array[@]}
do
    echo ${item}
done

# 删除整个数组,打印内容为空
unset array
for item in ${array[@]}
do
    echo ${item}
done