首页 Shell 变量
文章
取消

Shell 变量

定义变量

和 C/C++ 一样,shell 也有变量,并且定义方式大同小异。

如:name=Otokazename='Otokaze'name="Otokaze"

三种方式都可以,并且不需要指明变量类型,因为它们本质都是字符串。

但是,如果变量值存在空白符(如:空格),则必须使用引号包围起来。

单引号和双引号是有区别的,具体细节在后文有说明:单双引号区别

给 shell 变量定义、赋值、初始化时,= 两边不能有空格等空白字符。

从标准输入读取

除了普通的变量定义方式,我们也可以获取用户的输入,并将其存储在变量中;

语法:read var_name,当运行到read所在行时,当前 shell 进程阻塞,等待用户输入;

当用户输入完成,并键入回车后,当前进程继续执行,输入的字符串(不包含换行符)将保存至var_name中。

变量命名规则

只能以字母_开头,后面可跟字母数字_

变量初始化

在定义变量的时候必须进行赋值(称为:初始化),如 name='Otokaze',也可以赋空值:name=""

shell 允许你直接使用未定义/赋值的变量,未定义变量在字符串上下文中为空串,数值上下文中为 0。

引用变量值

定义变量后就可以使用这个变量了,比如我要打印 name 变量的值:echo ${name}echo $name

注意,在引用变量时,必须加上$,并且最好加上{}来标识边界,这是一个很好的编程习惯!

假设name=123,则${name}s扩展为123s;而$names扩展为空串,因为我们未定义names变量。

重新赋值

一个变量被定义后,可以被重新赋值,变量名前不用加$。如:name="Google"

可以这样简单记忆:

  • 定义/写入 变量值时,不带$
  • 引用/读取 变量值时,带上$

只读变量

有时候我们想定义一个常量,或者叫只读变量;

在 C/C++ 中使用关键字const,在 shell 中使用readonly

  • readonly MAX_SIZE=100,直接定义;
  • MAX_SIZE=100; readonly MAX_SIZE,将变量设置为只读。

任何尝试修改或删除只读变量的操作都会产生 MAX_SIZE: readonly variable 错误。

删除变量

使用unset命令,可以一次性删除多个变量。

如:unset nameunset var_a var_b var_c

只读变量不可以用 unset 删除,它的生命周期和 shell 进程一样长。

变量作用域

  • 局部变量:在函数中使用local关键字定义的变量是局部变量。局部变量只能在 函数上下文 使用;local 变量在函数被调用时初始化,在函数返回时被自动释放。

  • 全局变量:未使用local关键字定义的变量都是全局变量。全局变量在 shell 进程结束时、执行unset时,才会被释放。如非必要,请避免创建全局变量,尽量使用 local。

  • 环境变量:使用export 变量名可以将全局变量导出为环境变量,使用export -n 变量名撤销导出。环境变量可以使用env命令查看,子进程会继承(拷贝)父进程的环境变量。

单双引号区别

单引号的特点:

  • 单引号中的任何字符都会原样输出,比如 变量引用${}、命令替换$() 都不会执行,原样输出;
  • 单引号字符串中不允许出现单引号,就算是使用反斜杠转义也不行,也就是说单引号必须成对出现!

双引号的特点:

  • 可以进行 变量引用${}、命令替换$() 等操作;
  • 允许转义字符,可以包含单引号(无需转义),可以包含双引号(需要转义)。

无论是单引号还是双引号,它们都可以用来存储多行字符串(也就是字符串可以跨行)。

获取字符串长度

使用#号,如:url="www.zfl9.com",则 echo ${#url} 输出 12。

提取子串

索引值从 0 开始,支持负数索引,从-1开始(需要加前导0,见下):

  • echo ${url:3:5},输出".zfl9",3 表示从索引 3 开始,5 表示提取 5 个字符;
  • echo ${url:0-8:4},输出"zfl9",0-8 表示从索引 -8 开始,4 表示提取 4 个字符;
  • echo ${url:3},输出".zfl9.com",如果省略长度,则默认提取后面的所有字符;
  • echo ${url:0-1},输出"m",因为没有指定长度,所以默认提取后面的所有字符。

删除子串

操作符:

  • ### 操作符:从字符串 左边 匹配子串,然后删除;
  • %%% 操作符:从字符串 右边 匹配子串,然后删除。

匹配模式:

  • 可使用 glob 通配符,如 ?*[][^]
  • #% 操作符中的 *最短匹配(非贪婪);
  • ##%% 操作符中的 *最长匹配(贪婪)。

最短匹配:

  • echo ${url#w*.},最短匹配(左),输出"zfl9.com"
  • echo ${url%.*},最短匹配(右),输出"www.zfl9"

最长匹配:

  • echo ${url##w*.},最长匹配(左),输出"com"
  • echo ${url%%.*},最长匹配(右),输出"www"

替换子串

  • echo ${url/./*},仅替换一次,输出"www*zfl9.com"
  • echo ${url//./*},替换所有匹配的子串,输出"www*zfl9*com"
本文由作者按照 CC BY 4.0 进行授权

Shell 脚本入门

Shell 数组