Bash中的变量类型,你知道几种?

你必须非常努力,才能看起来毫不费力!

微信搜索公众号[ 漫漫Coding路 ],一起From Zero To Hero !

前言

与 Java、Go 等编程语言类似,Bash 中也可以自定义变量,那么如何自定义变量呢?除了自定义变量之外,Bash中还有没有其他类型的变量供我们使用呢?一起来学习吧!

变量分类

Bash 中,变量主要分为以下四种类型:

  • 自定义变量:类似Java、Go语言中的自定义变量,灵活性最高;
  • 环境变量:主要保存和系统环境相关的变量,系统已经定义好了很多环境变量,同时允许用户新增自定义环境变量,灵活性较高;
  • 位置参数变量:这种变量主要是用来向脚本中传递参数或者数据用的,参数名不能自定义,变量的作用也是固定的,只能更改值;
  • 预定义变量:Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。

由于内容较多,我们分为两篇文章来学习,本篇文章主要学习前两种变量:自定义变量和环境变量。

自定义变量

Java 中,你可以使用类似 int i = 1 的形式定义一个变量,同样在 Bash 中,你也可以定义变量,需要遵循以下几点规则:

  • 变量名可以由字母、数字、下划线组成,但是不能以数字开头
  • 变量与值之间通过 = 连接,中间不能有空格
  • 变量的值如果有空格,需要用单引号或者双引号包括
  • 在变量的值中,可以使用 “\” 符号进行转义
  • 如果需要追加变量的值,需要使用双引号包含"$变量名" 或者 ${变量名包含}
  • Bash定义的变量默认都是字符串类型的,如果要进行数值运算,必须指定变量类型为数值类型

用户变量也可以称为本地变量,因为自定义变量只在当前 Shell 中生效,其他 Shell 不能使用。

示例

# 变量与值通过 '=' 连接
[root@VM-0-5-centos ~]# name=lifelmy

# 变量与值中间不能有空格
[root@VM-0-5-centos ~]# name = lifelmy
-bash: name: 未找到命令

# 变量名不能使用数字开头,
[root@VM-0-5-centos ~]# 2name=lifelmy     
-bash: 2name=lifelmy: 未找到命令

# 值如果有空格,需要使用单引号或者双引号包括
[root@VM-0-5-centos ~]# title=this is a title
-bash: is: 未找到命令
[root@VM-0-5-centos ~]# title="this is a title"
[root@VM-0-5-centos ~]# echo $title
this is a title

# 变量的值可以使用转义符进行转义
[root@VM-0-5-centos ~]# name=\lifelmy
[root@VM-0-5-centos ~]# echo $name
lifelmy
[root@VM-0-5-centos ~]# name=\\lifelmy
[root@VM-0-5-centos ~]# echo $name
\lifelmy

# 变量值的追加
[root@VM-0-5-centos ~]# name=lifelmy
[root@VM-0-5-centos ~]# name1=${name}123
[root@VM-0-5-centos ~]# name2="$name"456
[root@VM-0-5-centos ~]# echo $name1
lifelmy123
[root@VM-0-5-centos ~]# echo $name2
lifelmy456

# 命令的结果赋值给变量
[root@VM-0-5-centos ~]# now=$(date)
[root@VM-0-5-centos ~]# echo $now
20211114日 星期日 13:48:43 CST

变量调用

使用 $变量名 可以调用变量

[root@VM-0-5-centos ~]# name=lifelmy
[root@VM-0-5-centos ~]# echo $name
lifelmy

变量查看

使用 set 命令可以查看所有变量(包括环境变量)

[root@VM-0-5-centos ~]# set | grep name
_name=lifelmy
name=lifelmy
name1=lifelmy123
name2=lifelmy456

变量删除

使用 unset 可以删除变量

[root@VM-0-5-centos ~]# name=lifelmy
[root@VM-0-5-centos ~]# echo $name
lifelmy
[root@VM-0-5-centos ~]# unset name
[root@VM-0-5-centos ~]# echo $name


数值运算

自定义变量的类型默认是字符串类型,无法进行数值计算:

[root@VM-0-5-centos ~]# aa=1
[root@VM-0-5-centos ~]# bb=2
[root@VM-0-5-centos ~]# cc=$aa+$bb
[root@VM-0-5-centos ~]# echo $cc
1+2

那么如何进行数值运算呢?在介绍之前,我们先来学习一个命令,该命令用于查看、设置变量的类型:

declare [+/-] [选项] 变量名

选项:
-: 给变量设定属性类型
+: 取消变量的类型属性
-i: 将变量声明为整数型(integer)
-x: 将变量声明为环境变量
-p: 显示指定变量被声明的类型

declare示例

[root@VM-0-5-centos ~]# name=lifelmy

# 默认是字符串类型
[root@VM-0-5-centos ~]# declare -p name
declare -- name="lifelmy"

# 声明为环境变量后,再次查看变成了 -x
[root@VM-0-5-centos ~]# export name
[root@VM-0-5-centos ~]# declare -p name
declare -x name="lifelmy"

# 声明为整数类型
[root@VM-0-5-centos ~]# declare -i age
[root@VM-0-5-centos ~]# age=18
[root@VM-0-5-centos ~]# declare -p age
declare -i age="18"

接下来我们介绍三种数值计算的方法:

  1. 使用 declare 声明
[root@VM-0-5-centos ~]# a=11
[root@VM-0-5-centos ~]# b=12

# 声明c为整数
[root@VM-0-5-centos ~]# declare -i c
[root@VM-0-5-centos ~]# c=$a+$b
[root@VM-0-5-centos ~]# echo $c
23
  1. 使用 exprlet 运算工具
[root@VM-0-5-centos ~]# a=1
[root@VM-0-5-centos ~]# b=2

# 注意:'+'号左右两侧必须有空格
[root@VM-0-5-centos ~]# c=$(expr $a + $b)
[root@VM-0-5-centos ~]# echo $c

# 不需要有空格
[root@VM-0-5-centos ~]# let d=$a*$b
[root@VM-0-5-centos ~]# echo $d
2
  1. 使用运算式

使用 $((运算式))$[运算式]

# $((运算式))  或 $[运算式]

[root@9c12e0d24857 /]# a=2
[root@9c12e0d24857 /]# b=3
[root@9c12e0d24857 /]# c=$(($a+$b))
[root@9c12e0d24857 /]# echo $c
5
[root@9c12e0d24857 /]# d=$[$a+$b]
[root@9c12e0d24857 /]# echo $d
5

在实际使用中,最常用的是第三种方式。

环境变量

前面讨论的自定义变量,只会在 当前Shell 中生效,而环境变量会在 当前Shell 以及这个 Shell 的所有 子Shell 中生效。如果把环境变量写入相应的配置文件,那么这个环境变量就会在所有的 Shell 中生效。

什么叫做 子Shell 呢? 我们在 Shell 编程初体验 查看支持的Shell 章节讨论过,可以通过执行命令切换到其他 Shell 中,那么当前 Shell 就是 父Shell,切换后的 Shell 就是 子Shell

设置环境变量

export 变量名=变量值

如果变量已经存在,可直接使用 export 声明

export 变量名

查询环境变量

env

删除环境变量

unset 变量名

使用环境变量

和自定义变量类似,使用 $变量名 取值

echo $变量名

示例一

创建并通过进程树查看 子Shell

# 1. 在当前Bash中执行该命令,能够找到如下输出的一条链路
[root@VM-0-5-centos ~]# pstree
systemd──sshd──sshd───bash───pstree

# 2. 然后在当前Bash中开启一个新的Bash,即一个子Shell
#    再查看进程树相应链路,发现多了个bash
[root@VM-0-5-centos ~]# bash
[root@VM-0-5-centos ~]# pstree
systemd─sshd─┬─sshd───bash───bash───pstree


# 3. 退出子Shell,查看进程树,发现子Shell没有了
[root@VM-0-5-centos ~]# exit
exit
[root@VM-0-5-centos ~]# pstree
systemd──sshd──sshd───bash───pstree

示例二

设置环境变量

# 1. 设置了一个自定义变量,并通过两种方式设置了两个环境变量age 和 gender
[root@VM-0-5-centos ~]# name=lifelmy
[root@VM-0-5-centos ~]# age=18
[root@VM-0-5-centos ~]# export gender=male
[root@VM-0-5-centos ~]# export age

# 2. 通过 set 命令查看所有变量,都可以查到
[root@VM-0-5-centos ~]# set | grep name=
name=lifelmy
[root@VM-0-5-centos ~]# set | grep age=
age=18
[root@VM-0-5-centos ~]# set | grep gender=
gender=male

# 3. 进入一个 子Shell
[root@VM-0-5-centos ~]# bash

# 4. 发现只有两个环境变量,可以在子Shell中可以查询到
[root@VM-0-5-centos ~]# set | grep name=
[root@VM-0-5-centos ~]# set | grep age=
age=18
[root@VM-0-5-centos ~]# set | grep gender=
gender=male

示例三

查看、使用、删除环境变量

# 使用 env 命令查看环境变量
[root@VM-0-5-centos ~]# env
gender=male
age=18
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
......

# 使用环境变量
[root@VM-0-5-centos ~]# echo $age
18
[root@VM-0-5-centos ~]# echo $gender
male

# 删除环境变量
[root@VM-0-5-centos ~]# unset age

常见系统环境变量-PATH

PATH下面的内容,是系统用于查找命令的路径(使用":"分隔)

[root@VM-0-5-centos ~]# env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

我们可以在PATH后,按照规定的格式,追加自定义的文件夹

PATH="$PATH":/root/hello

Shell 编程初体验 编写第一个Shell脚本 章节介绍过,想要执行脚本,必须使用相对路径或者绝对路径。对于 Linux 中的这些系统命令,例如 ls、cd、mkdir,和我们自己写的脚本文件一样,也是可执行程序,为什么输入这些命令时,不需要使用相对或绝对路径呢?那是因为当我们输入了一个命令后,Linux 会在 PATH 下所有文件夹中寻找这个可执行程序,如果找到了就可以执行,如果找不到就会报错 “未找到命令”,这里的未找到,就是在 PATH 对应的路径中未找到。

比如我们写一个脚本,输出 “hello world”,默认只能使用相对或绝对路径执行。

[root@VM-0-5-centos ~]# vim hello.sh

#!/bin/bash
echo "hello world"

[root@VM-0-5-centos ~]# chmod 755 hello.sh
# 相对路径
[root@VM-0-5-centos ~]# ./hello.sh
hello world
# 绝对路径
[root@VM-0-5-centos ~]# /root/hello.sh
hello world

但是如果我们把该脚本添加到 PATH 下面的一个文件夹中,就可以直接使用了!同时按 “TAB” 键也会进行补全! 可见 “TAB” 键也是在 PATH 下面的路径中查找的!

[root@VM-0-5-centos ~]# cp hello.sh /sbin/
[root@VM-0-5-centos ~]# hello.sh
hello world

但是我们并不推荐使用这种方式,因为 “/sbin” 目录就是用来保存系统命令的,把我们自定义的命令脚本放进去,会将文件搞混。而更优雅的方式,则是将我们脚本所在的文件夹,追加到 PATH 中。

# 1. 删除上一步复制的hello.sh
[root@VM-0-5-centos ~]# rm /sbin/hello.sh
rm:是否删除普通文件 "/sbin/hello.sh"?y

# 将当前脚本文件所在目录,添加到 PATH 中
[root@VM-0-5-centos ~]# PATH="$PATH":/root
[root@VM-0-5-centos ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root
[root@VM-0-5-centos ~]# hello.sh
hello world

以上的改动只会在当前Shell以及子Shell中生效,因为我们暂未将其写入环境变量配置文件中去。

常见系统环境变量-PS1

定义系统提示符的变量,就是我们输入命令前的提示符,当前我的就是 [root@VM-0-5-centos ~]

PS1 也是属于环境变量的一种,但是使用 env 命令查询不到,使用 set 可以查找到

[root@VM-0-5-centos ~]# set | grep PS1
PS1='[\u@\h \W]\$ '
代码说明
\d显示日期,格式为 “星期 月 日”
\h显示简写主机名,如默认主机名为"localhost"
\t显示24小时制事件,格式为"HH:MM:SS"
\T显示12小时制事件,格式为"HH:MM:SS"
\A显示24小时制事件,格式为"HH:MM"
\u显示当前用户名
\w显示当前所在目录的完整名称
\W显示当前所在目录的最后一个目录
\#执行的第几个命令
\$提示符,如果是root用户显示"#",普通用户提示符为"$"

我们可以改动下PS1的值来看下效果:

[root@VM-0-5-centos ~]# PS1='[\u@ \t \W]\$ '
[root@ 15:47:59 ~]# ls
hello.sh

这种改动也是只是临时生效,需要永久生效需要写入配置文件。当然这里只是体验下,系统默认的已经够用了,其实也无需更改。

总结

本篇文章介绍了Bash 中的变量分类:自定义变量、环境变量、位置参数变量和预定义变量,并详细介绍了前两种:

  1. 自定义变量的定义、查看、调用以及如何进行数值计算;
  2. 环境变量的设置、查看、使用,并介绍了两种常见的环境变量:PATH 和 PS1。

更多

个人博客: https://lifelmy.github.io/

微信公众号:漫漫Coding路

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值