1 变量概述
变量即在程序运行过程中它的值是允许改变的量。
变量是用一串固定的字符串去表示不固定的内容。
变量表示命令的内存空间,将数据放在内存空间中,通过变量名引用,获取数据。
变量的作用:
用来存放系统和用户需要使用的特定参数(值)。
- 变量名:使用固定的名称,由系统预设或用户定义。
- 变量值:能够根据用户设置、系统环境的变化而变化。
1.1 变量类型
变量赋值: 变量名=变量值(name=value)
bash变量类型:
1、根据变量的生效范围可分为:
- 环境变量(全局变量):全局生效,在任何bash环境中都可以识别。
- 局部变量:生效范围为当前shell进程。对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效。
- 本地变量:生效范围为当前shell进程中某代码片断,通常指函数。 只能在定义它们的函数/脚本内部中使用。
2、根据是否由系统定义可分为:
- 内置变量:由系统维护,用于设置工作环境。如PS1,PATH,HISTSIZE, HOSTNAME,USER。
- 自定义变量:由用户自己定义、修改和使用。
3、特殊变量:
-
环境变量(全局变量):全局生效,在任何bash环境中都可以识别。:
-
只读变量:read only, 只可以读取不可以更改 。
-
位置变量: 通过命令行给脚本传递参数 。n(n是正整数),n(n是正整数),n(n是正整数),{10} 要加花括号。
-
预定义变量:用来保持脚本程序的执行信息。
- $0 :当前脚本名称(如果是软链接,显示当前软链接文件名)。
- $? :查看上一次命令的执行状态,返回0为正常,非0为错误。
- $* :返回所有参数,当整体返回。
- $@ :返回所有参数,当个体返回。
- $# :获取当前shell命令行中参数的总个数。
- $_ :在此之前执行的命令或脚本的最后一个参数。
$$:获取当前进程的PID。
1.2 变量的命名要求
- 区分大小写
- 不能使程序中的保留字和内置变量名称:如:if, for,hostname。
- 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反。
- 使用英文时,尽量使用词义通俗易懂,如PATH。
- 大驼峰 StudentFirstName
- 小驼峰 studentFirstName
- 下划线 student_name
1.3 变量作用范围
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。
可以通过内部命令export将指定的变量为全局变量(即环境变量),使用户定义的变量在所有子shell环境中可以继续使用。
方法:
-
法一,设置全局变量:
- export name=value
- 或 declare -x name=value
-
法二,将局部变量转变为全局变量:export name
示例:
步骤1、先设置一个局部变量color,使用bash命令进入子shell环境,查看变量是否有效;
步骤2、之后使用export命令将局部变量转换为环境变量,进入子shell环境,查看变量是否有效。
# 设置局部变量color
[root@localhost ~]# color=red //设置局部变量color
[root@localhost ~]# echo $color
red
[root@localhost ~]# bash //进入子shell环境
[root@localhost ~]# echo $color //查看变量color,为空,无效
[root@localhost ~]# exit //退出当前shell,返回上一级shell环境
exit
# 将局部变量color转换为全局变量
[root@localhost ~]# export color //将局部变量color转换为全局变量
[root@localhost ~]# bash //进入子shell环境
[root@localhost ~]# echo $color //查看变量color,有效
red
1.4 几个符号的作用
说明:
双引号" ":会把引号的内容当成整体来看待。强引用,识别变量,允许通过$符号引用其他变量值。
单引号' ':会把引号的内容当成整体来看待。弱引用,禁止引用其他变量值,单引号内的内容都会被认为是普通字符。
反撇号` ` 和 $() :调用命令执行后输出的结果。如果存在嵌套,不能使用反撇号。
花括号{ } :定义变量范围。 echo ${color}${price}
示例:
# 当引号内只表示字符串时,使用双引号或单引号都可以。
[root@localhost ~]# echo "abc"
abc
[root@localhost ~]# echo 'abc'
abc
# 使用单引号或双引号时,引号内的内容会被当做一个整体。
[root@localhost test]# touch a b //创建a和b两个文件
[root@localhost test]# ll
总用量 0
-rw-r--r--. 1 root root 0 4月 2 21:44 a
-rw-r--r--. 1 root root 0 4月 2 21:44 b
[root@localhost test]# touch "a b" //创建名称为"a b"的一个文件
[root@localhost test]# ll
总用量 0
-rw-r--r--. 1 root root 0 4月 2 21:44 a
-rw-r--r--. 1 root root 0 4月 2 21:45 a b
-rw-r--r--. 1 root root 0 4月 2 21:44 b
# 双引号可以通过$符号引用变量值,单引号禁止引用变量值,单引号内的内容都被认为是普通字符。
[root@localhost test]# echo "$HOME"
/root
[root@localhost test]# echo '$HOME'
$HOME
# 反撇号和$(),可以调用命令执行后输出的结果。
[root@localhost ~]# pwd
/root
[root@localhost ~]# echo `pwd`
/root
[root@localhost ~]# echo $(pwd)
/root
# 如果存在嵌套,不能使用反撇号。可以使用$()。
[root@localhost ~]# echo `echo `pwd``
pwd
[root@localhost ~]# echo $(echo `pwd`)
/root
[root@localhost ~]# echo $(echo $(pwd))
/root
1.5 展开命令行
展开命令执行顺序:
把命令行拆分成单个命令词
展开别名
展开花括号的声明 {}
展开波浪符声明 ~
命令替换 $()和``
再次把命令行拆分成命令词
展开文件通配符*、?、[abc]等待
准备I/O重定向 < 和 >
运行命令
2 局部变量
定义变量: 变量名=变量值
引用变量: $变量名 或 ${变量名}
查看变量:
- echo $变量名:查看单个变量
- set:查看所有变量,包括局部变量和环境变量
取消变量: unset 变量名
作用范围: 仅在当前shell环境中有效,无法在子shell环境中使用。
3 环境变量
3.1 系统内置环境变量
1、由系统提前创建,用来设置用户的工作环境。
2、使用env命令查看所有环境变量:
[root@localhost ~]# env //查看所有环境变量,这里只截取部分进行展示
XDG_SESSION_ID=1
HOSTNAME=localhost.localdomain
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.72.100 55445 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root
3、需要记住的常用环境变量:
- $PATH 表示可执行文件的默认路径
- $USER 表示用户名称
- $HOME 表示用户的宿主目录
- $LANG 表示语言和字符集
- $PWD 表示当前所在工作目录
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# echo $USER
root
[root@localhost ~]# echo $HOME
/root
[root@localhost ~]# echo $LANG
zh_CN.UTF-8
[root@localhost ~]# echo $PWD
/root
4、环境变量的特性:
- 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。
- 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程。
- 一般只在系统配置文件中使用,在脚本中较少使用。
3.2 环境变量的配置文件
自定义的环境变量只是临时生效,退出系统后就会失效。需要将自定义的环境变量放入配置文件中,才会永久生效。配置文件可以用来长期变更或设置环境变量。
全局配置文件:
- /etc/profile,修改此文件会作用于所有用户。
用户独立的配置文件:
- ~/.bash_profile,修改这个文件只作用于当前用户。
示例:
1)将脚本文件所在目录添加进可执行文件的默认路径PATH中,则可直接通过文件名称执行该程序。
[root@localhost ~]# echo "echo 'hello stars'" > /data/hello.sh //写一个脚本
[root@localhost ~]# cat /data/hello.sh
echo 'hello stars'
[root@localhost ~]# chmod a+x /data/hello.sh //为脚本增加执行权限
[root@localhost ~]# vim /etc/profile //编辑全局配置文件
---------------------------
export PATH=$PATH:/data //将/data加入变量PATH中
[root@localhost ~]# source /etc/profile //刷新文件,使立即生效
[root@localhost data]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/data
[root@localhost ~]# hello.sh //现在可直接使用文件名执行该脚本
hello stars
2)在当前用户环境中,添加系统的空闲等待时间TMOUT,等待15分钟后自动登出。
[root@localhost ~]# echo $TMOUT //查看TMOUT,没有该变量
[root@localhost ~]# vim ~/.bash_profile //编辑用户的配置文件,加入变量TMOUT
----------------------
TMOUT=900 //超时900秒后自动注销
[root@localhost ~]# source ~/.bash_profile //刷新文件,使立即生效
[root@localhost ~]# echo $TMOUT //查看变量TMOUT,显示为900
900
4 只读变量
我们在定义shell变量时,默认定义的变量是可以被修改的,但有一种变量是不能修改的,就是只读变量。
只读变量只能被赋值一次。只读变量在取得初始值之后,只能进行读取操作,不能重新赋值或删除。
定义变量:
- 第一步:name=value # 定义一个变量
- 第二步:readonly name # 使用 readonly 来修饰该变量 ,表明只读
[root@localhost data]# year=2022 //定义一个变量year
[root@localhost data]# readonly year //使用 readonly 修饰该变量 ,表明只读
[root@localhost data]# echo $year
2022
[root@localhost data]# year=2000 //无法重新赋值
-bash: year: 只读变量
[root@localhost data]# unset year //无法使用unset删除
-bash: unset: year: 无法反设定: 只读 variable
5 位置变量
位置变量也称为位置参数。
使用$n表示,n为数字序列号,且必须为整数。
如:$1、$2、…、$9 、${10}、${11}。
两位数需要加花括号{},不然$10会被识别为:$1和0 。
示例:
[root@localhost ~]# cat weizhi.sh
#!/bin/bash
echo "$1" #显示位置1的参数
echo "$2" #显示位置2的参数
echo "$3" #显示位置3的参数
[root@localhost ~]# bash weizhi.sh aaa bbb ccc
aaa //对应$1
bbb //对应$2
ccc //对应$3
6 预定义变量
预定义变量是系统定义好的变量,用来保持脚本程序的执行信息。
可以直接使用这些变量,不能直接为这些变量赋值。
| 变量 | 作用 |
|---|---|
| $? | 表示前一条命令执行后的返回状态。返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常。 |
| $* | 表示所有位置参数的内容。当整体返回。(将输入的参数作为一个单词) |
| $@ | 表示所有位置参数的内容。当个体返回。可作为数组。(将参数内容分割成n份,每份作为独立个体) |
| $# | 表示命令行中位置参数的总个数。 |
| $0 | 表示当前脚本名称(如果是软链接,显示当前软链接文件名)。 |
| $_ | 表示在此之前执行的命令或脚本的最后一个参数。 |
| $$ | 获取当前进程的PID。 |
$* 和 $@的区别:
- 不加双引号的话,
$*和$@都代表脚本后面跟的所有参数。 - 加上双引号的话,"
$*"会把所有参数当作一个整体去看待(此时参数数量为1),"$@"会把脚本后面跟的每一个参数当作一个个体去看待。
示例:
1)测试 $? 的作用。
[root@localhost ~]# ls /opt
rh
[root@localhost ~]# echo $? //返回0表示执行正常
0
[root@localhost ~]# ls /xxx
ls: 无法访问/xxx: 没有那个文件或目录
[root@localhost ~]# echo $? //返回非0表示执行出现异常
2
[root@localhost ~]# ls /opt /xxx
ls: 无法访问/xxx: 没有那个文件或目录
/opt:
rh
[root@localhost ~]# echo $?
2
2)测试 $0、$$、$#、$@ 的作用。
[root@localhost ~]# cat special.sh
#!/bin/bash
echo "当前脚本名称为:$0"
echo "当前程序的PID为:$$"
echo "位置参数的个数为:$#"
echo "显示所有的位置参数:$@"
[root@localhost ~]# bash special.sh aa bb cc
当前脚本名称为:special.sh
当前程序的PID为:4042
位置参数的个数为:3
显示所有的位置参数:aa bb cc
7 read 从键盘输入内容为变量赋值
read可以从键盘输入变量值,即将键盘输入的内容变成变量值。
格式: read 变量名
常用选项:
- -p:后面跟提示信息,即在输入前打印提示信息。
- -s:安静模式,在输入字符时不再屏幕上显示,例如密码。
- -t:后面跟秒数,定义输入字符的等待时间。
- -n:后跟一个数字,定义输入文本的长度。
- -a:后跟一个变量,该变量会被认为是个数组。
示例:
1)赋值演示。
[root@localhost ~]# read price //为变量赋值
100
[root@localhost ~]# echo $price //查看变量值
100
[root@localhost ~]# read -p "请输入您的年龄:" age
请输入您的年龄:20
[root@localhost ~]# echo $age
20
2)在脚本中使用。
[root@localhost ~]# cat pass.sh
#!/bin/bash
read -p "请输入您的姓名:" name
echo "您的姓名是:$name"
[root@localhost ~]# bash pass.sh
请输入您的姓名:nancy
您的姓名是:nancy
8 四个配置文件的作用
1、/etc/profile 文件
系统级的配置文件,开机时系统自动加载该文件中的配置。
系统每次启动都会自动执行/etc/profile 文件里的命令,这个文件是对全局有效的(所有的shell环境和用户)。
2、~/.bash_ profile 文件
不同用户登录系统时,会自动执行自己家目录中的~/ .bash_ profile 文件中的命令,之后自动执行~/ . bashrc。(因为~/ .bash_ profile文件中规定了,如果~/ . bashrc是个文件,则执行该文件)。
3、~/.bashrc 文件
当前用户每切换一个shell环境都会自动加载~/ . bashrc 文件中的配置 ,之后自动执行/etc/bashrc文件。(因为~/ . bashrc文件中规定了,如果/etc/bashrc是个文件,则执行该文件)。
4、/etc/bashrc 文件
/etc/bashrc针对所有用户,用户每切换一个shell环境都会自动执行。
5、/etc/skel/ 目录
/etc/skel/是用来存放新用户配置文件的目录,当我们添加新用户的时候,这个目录下的所有文件会自动被复制到新添加的用户的家目录下。这个目录下的所有文件都是隐藏文件(以.开头的文件)。
该目录中包括 .bash_logout 、 .bash_profile 、 .bashrc 这三个配置文件。
9 重点总结
1、全局变量和局部变量:
- 环境变量(全局变量):在当前shell环境和子shell环境(包括孙子shell环境)中都生效。
- 局部变量:只在当前shell环境中生效,子shell环境中无效。
2、设置、查看和删除变量的命令:
-
变量赋值:
- 方法1:变量名=变量值(name=value)
- 方法2:read 变量名, 之后从键盘输入中获取变量名的值
-
设置环境变量:export name=value 或 export name
-
设置只读变量:readonly name 。只读变量不可删除或重新赋值。
-
查看变量和变量值:
- env:查看所有环境变量。
- set:查看所有变量,包括局部变量和环境变量。
-
删除变量:unset name
3、几个符号的作用:
双引号" ":强引用,识别变量,允许通过$符号引用其他变量值。会把引号的内容当成整体来看待。
单引号' ':弱引用,不会识别变量,禁止引用其他变量值,单引号内的内容都会被认为是普通字符。
反撇号` ` 和 $() :调用命令执行后输出的结果。如果存在嵌套,不能使用反撇号。
花括号{ } :定义变量范围。