Shell变量
1 变量的定义与使用
1.1 变量概述
各种 Shell 环境中都使用到了“变量”的概念。
Shell 变量用来存放系统和用户需要使用的特定参数(值),而且这些参数可以根据用户的设定或系统环境的变化而相应变化。
通过使用变量,Shell 程序能够提供更加灵活的功能,适应性更强。
语法:变量名=变量值
var1="abc"
等号两边没有空格
1.2 变量名的命名规则
只包含字母、数字和下划线
不能以数字开头
避免使用 Shell 关键字,例如 if、then、else、fi、for、while 等
使用大写字母表示常量,例如PI=3.14
避免使用特殊符号,可能与Shell 的语法产生冲突
避免使用空格,空格通常用于分隔命令和参数
- 有效的shell变量名
name="tom"
PATH="/bin/"
var2="abc"
_var="123"
- 无效的shell变量名
# 避免适用于关键字
if="value"
# 避免使用特殊符号
var_$=15
?var=16
user*name="jery"
1.3 变量的使用
使用一个定义过的变量,只要在变量名前面加美元符号$
即可
yourname="tom"
echo $your_name
echo ${your_name}
变量名外面的花括号是可选的,加花括号是为了帮助解释器识别变量的边界,推荐给变量加上花括号,这是个好的编程习惯。
2 变量的类型
常见 Shell 变量的类型包括:
自定义变量
环境变量
只读变量
位置变量
预定义变量
2.1 自定义变量
定义变量是由系统用户自己定义的变量,只在用户自己的Shell 环境中有效,因此又称为本地变量。
- 定义一个新的变量时,一般不需要提前进行声明,而是直接指定变量名称并赋给初始值(内容)即可。
py="python"
echo $py
- 对于未定义的变量,将显示为空值。
echo $python
- 变量名称容易和紧跟其后的其他字符相混淆时,需要添加大括号“{}”将其括起来,否则将无法确定正确的变量名称。
py="python"
# echo $py3.13
echo ${py}3.13
2.2 双引号""
双引号主要起界定字符串的作用,特别是当要赋值的内容中包含空格时,必须以双引号括起来。
# py=python 3.13
py="python 3.13"
在双引号范围内,使用“$”符号可以引用其他变量的值(变量引用),从而能够直接调用现有变量的值来赋给新的变量。
version=3.13
py="python $version"
echo $py
2.3 单引号’’
当要赋值的内容中包含$、“、\等具有特殊含义的字符时,应使用单引号括起来。
在单引号的范围内,将无法引用其他变量的值,任何字符均作为普通字符看待。
但赋值内容中包含单引号(‘)时,需使用\’符号进行转义,以免冲突。
version=3.13
py='python $version'
echo $py
2.4 反撇号``
反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。
反撇号括起来的范围内必须是能够执行的命令行,否则将会出错。
path=`which useradd`
echo $path
在一行命令中查找useradd 命令程序的位置并列出其详细属性
ls -lh `which useradd`
述操作相当于连续执行了两条命令
先通过 which useradd 命令查找出 useradd命令的程序位置,然后根据查找结果列出文件属性。
执行过程中,会用 which useradd 命令的输出结果替换整个反撇号范围。
2.5 $()
用反撇号难以在一行命令中实现嵌套命令替换操作,这时可以改用“$()”来代替反撇号操作,以解决嵌套的问题。
随着shell脚本编程的发展, $ ()已经成为主流的命令替换方式,而反引号在一些新的shell版本中可能逐渐被淘汰。
now_time=$(date)
echo $now_time
ls -lh $(which useradd)
2.6 read命令
2.6.1 赋值
read命令可以用来给变量赋值
执行时将从标准输入设备(键盘)读入一行内容,并以空格为分隔符,将读入的各字段依次赋值给指定的变量。
若变量值的个数大于变量的个数,多余的变量值赋值给最后一个变量。
若变量值的个数小于变量的个数,多余的变量不赋值。
2.6.2 交互
read 命令用来提示用户输入信息,从而实现简单的交互过程。
- vim /test/test1.sh
#!/bin/bash
echo "请输入如要查询的命令(pwd mkdir touch):"
read b
which $b
echo "脚本执行完毕!"
为了使交互式操作的界面更加友好,提高易用性,read命令可以结合“-p”选项来设置提示信息,以便告知用户应该输入什么内容等相关事项。
- vim /test/test2.sh
#!/bin/bash
read -p "请输入要查询的命令(pwd mkdir touch):" a
which $a
echo "脚本执行完毕!"
2.7 数组输入
read -a 命令用于从标准输入读取一行,并将其分割成数组元素,以空格为分隔符。
-a 选项允许将输入的每个字段存储到一个数组中。
- vim /test/test3.sh
#!/bin/bash
read -p "请输入一句话:" -a line
echo "这就话是:${line}"
echo "第一个单词是:${line[0]}"
echo "第二个单词是:${line[1]}"
echo "第三个单词是:${line[2]}"
echo "脚本执行完毕!"
2.8 局部变量与全局变量
默认情况下,新定义的变量只在当前的 Shell 环境中有效,因此称为局部变量。
当进入子程序或新的子 Shell 环境时,局部变量将无法再使用。
在程序或脚本中定义的具有全局范围的变量,称为全局变量。
这意味着全局变量在整个程序或脚本的不同部分都是可见和可访问的,而不仅限于特定的函数、方法或代码块。
全局变量的特点:
全局范围: 全局变量在整个程序或脚本的各个部分都是可见和可访问的。
持久性: 全局变量的生命周期与程序的执行时间相同。它们在程序启动时创建,在程序结束时销毁。
共享性: 全局变量可以在程序的不同函数或方法之间共享数据。这样,多个函数可以使用和修改相同的全局变量。
全局变量潜在的副作用:
全局变量的使用可能导致副作用和潜在的复杂性。
因为全局变量是可访问的,所以它们可以被任何函数修改,这可能导致程序状态的不确定性和难以调试的问题。
2.9 export命令
为了使用户定义的变量在所有的子 Shell 环境中能够继续使用,减少重复设置工作,可以通过内部命令 export 将指定的变量导出为全局变量。
用户可以同时指定多个变量名称作为参数(无须使用“$”符号),变量名之间以空格分隔。
使用 export 导出全局变量的同时,也可以为变量进行赋值,这样在新定义全局变量时就不需要提前进行赋值了。
2.10 执行方式的区别
./和source在Linux中执行脚本时有显著的区别:
- 执行环境
./:在当前shell的子shell中执行脚本,不改变当前shell的环境
source:在当前shell中执行脚本,影响当前shell环境
- 权限需求
/:要求脚本文件具备可执行权限
source:不需要脚本文件具备可执行权限,只需可读权限
- 变量作用域
./:在子shell中设置的变量在脚本执行完毕不会保存在当前shell中
source:在当前shall中执行的脚本,其设置的变量会保存在当前shell中
- 执行方式
./:脚本作为一个独立的程序运行
source:脚本中的命令在当前shell中逐行运行
- 使用场景
/:适用于执行独立的脚本程序,不需要共享环境变量
source:适用于加载环境变量配置文件或修改当前shell
综上所述:选择./还是source取决于是否需要脚本影响当前shell的环境和变量
2.11 环境变量
环境变量指的是出于运行需要而由 Linux 系统提前创建的一类变量,主要用于设置用户的工作环境,包括用户宿主目录、命令查找路径、用户当前目录、登录终端等。
环境变量的值由 Linux 系统自动维护,会随着用户状态的改变而改变。
2.11.1 env命令
使用 env 命令可以查看到当前工作环境下的环境变量,对于常见的一些环境变量应了解其各自的用途。
例如,变量 USER 表示用户名称,HOME 表示用户的宿主目录,LANG表示语言和字符集,PWD 表示当前所在的工作目录,PATH 表示命令搜索路径等。
env
2.11.2 PATH变量
PATH 变量用于设置可执行程序的默认搜索路径,当仅指定文件名称来执行命令程序时,Linux 系统将在 PATH 变量指定的目录范围查找对应的可执行文件,如果找不到则会提示“command not found”。
例如,helloworld.sh 脚本位于/test 目录下,若希望能直接通过文件名称来运行脚本,可以修改 PATH 变量以添加搜索路径,或者将HelloWorld.sh 脚本复制到现有搜索路径中的某个文件夹下。
2.12 全局配置文件
Linux 系统中,环境变量的全局配置文件为==/etc/profile==,在此文件中定义的变量作用于所有用户。
每个用户还有自己的独立配置文件(~/.bashrc)。
若要长期变更或设置某个环境变量,应在上述文件中进行设置。
修改只有当 root 用户下次登录时才会生效。
若希望立即生效,应手动修改环境变量,或者可以加载配置文件执行。
source /root/.bashrc
2.13 只读变量
Shell 变量中有一种特殊情况,一经设定其值是不可改变的,这种变量被称为只读变量。
在创建变量的时候可将其设置为只读属性,也可以将已存在的变量设置为只读属性,只读变量主要用于变量值不允许被修改的情况。
使用 readonly 命令将变量定义为只读变量,定义之后不能通过再次赋值的方式进行修改。
可以使用declare -p命令来查看变量的属性
declare -p path
2.14 位置变量
为了在使用 Shell 脚本程序时,方便通过命令行,为程序提供操作参数,Bash 引入了位置变量的概念。
当执行命令行操作时,第一个字段表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次赋值给位置变量。
位置变量也称为位置参数,使用$1
、$2
、$3
、…、$9
表示。例如,当执行命令行“ls -lh /boot/”时,其中第 1个位置变量为“-lh”,以$1
表示;第 2 个位置变量为“/boot/”,以$2
表示。
命令或脚本本身的名称使用$0
表示,虽然$0
与位置变量的格式相同,但是$0
属于预定义变量而不是位置变量。
- vim test4.sh
#!/bin/bash
echo "脚本名为:$0"
echo "第一个变量为:$1"
echo "第二个变量为:$2"
echo "第三个变量为:$3"
2.15 预定义变量
预定义变量是由 Bash 程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。
预定义变量使用“$”符号和另一个符号组合表示,较常用的几个预定义变量的含义如下:
$#:表示命令行中位置参数的个数
$*:表示所有位置参数的内容
$?:表示前一条命令执行后的返回状态,返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常。
$0:表示当前执行的脚本或程序的名称。
- vim test4.sh
#!/bin/bash
echo "脚本名为:$0"
echo "第一个变量为:$1"
echo "第二个变量为:$2"
echo "第三个变量为:$3"
echo "参数的个数为:$#"
echo "参数值分别为:$*"