首页 Shell 变量
文章
取消

Shell 变量

定义变量

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

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

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

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

使用单双引号其实是有区别的,具体的细节我会在后面进行详细解释。

从标准输入读取

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

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

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

变量命名规则

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

变量初始化

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

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

引用变量值

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

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

重新赋值

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

可以这样简单记忆:

  • 读取变量值时,必须加上$
  • 写入变量值时,不能加上$
  • 定义变量类似写入变量,不能加$

只读变量

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

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

readonly有两种用法:

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

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

并且只读变量不能被 unset 删除

删除变量

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

如:unset nameunset var_a var_b var_c

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

变量类型

注意,这里不是指变量存储的值的类型,它们都是字符串。变量类型有四种:

  • 局部变量,或者称为函数变量,即在函数中使用local关键字定义的变量都是局部变量。局部变量只能在函数内部使用;在函数被调用的时候初始化,在函数返回的时候回收释放。

  • 全局变量,即当前 shell 环境中定义的变量,一般我们定义的变量都是全局的,除非在函数中使用local关键字。注意,在函数中,如果不使用local定义变量,那么它默认就是全局变量!全局变量就相当于 C/C++ 中的静态变量 ,在 shell 退出的时候才被释放。

  • 环境变量,所有的环境变量都可以使用env命令查看,子进程会继承父进程的环境变量(拷贝一份)。我们可以使用export命令将全局变量导出为环境变量。只读变量也能导出为环境变量,它依旧只读。

  • shell变量,shell 进程设置的特殊变量,一部分是全局变量,一部分是环境变量,它们的存在都是为了保证 shell 的正常运行。

单双引号区别

单引号的特点:

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

双引号的特点:

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

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

获取字符串长度

使用#号,如: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 数组