Shell脚本变量部分超详细解析
变量的定义
【基本知识补充】
1. 变量是什么?
一句话概括:变量是用来临时保存数据的,该数据是可以变化的数据。
【注意】
- 单引号双引号敏感,单引号中不能有变量
- 命令等价于“$()”,反引号中的shell命令会被先执行
2. 什么时候需要定义变量?
- 如果某个内容需要多次使用,并且在代码中重复出现,那么可以用变量代表该内容。这样在修改内容的时候,仅仅需要修改变量的值。
- 在代码运作的过程中,可能会把某些命令的执行结果保存起来,后续代码需要使用这些结果,就可以直接使用这个变量。
3.变量如何定义?
*变量名=====变量值*
变量名:用来临时保存数据的
变量值:就是临时的可变化的数据
[root@MissHou ~]# A=hello 定义变量A
[root@MissHou ~]# echo $A 调用变量A,要给钱的,不是人民币是美元"$"
hello
[root@MissHou ~]# echo ${A} 还可以这样调用,不管你的姿势多优雅,总之要给钱
hello
[root@MissHou ~]# A=world 因为是变量所以可以变,移情别恋是常事
[root@MissHou ~]# echo $A 不管你是谁,只要调用就要给钱
world
[root@MissHou ~]# unset A 不跟你玩了,取消变量
[root@MissHou ~]# echo $A 从此,我单身了,你可以给我介绍任何人
4. 变量的定义规则
虽然可以给变量(变量名)赋予任何值;但是,对于变量名也是要求的!
㈠ 变量名区分大小写
[root@MissHou ~]# A=hello
[root@MissHou ~]# a=world
[root@MissHou ~]# echo $A
hello
[root@MissHou ~]# echo $a
world
㈡ 变量名不能有特殊符号
[root@MissHou ~]# *A=hello
-bash: *A=hello: command not found
[root@MissHou ~]# ?A=hello
-bash: ?A=hello: command not found
[root@MissHou ~]# @A=hello
-bash: @A=hello: command not found
特别说明:对于有空格的字符串给变量赋值时,要用引号引起来
[root@MissHou ~]# A=hello world
-bash: world: command not found
[root@MissHou ~]# A="hello world"
[root@MissHou ~]# A='hello world'
㈢ 变量名不能以数字开头
[root@MissHou ~]# 1A=hello
-bash: 1A=hello: command not found
[root@MissHou ~]# A1=hello
注意:不能以数字开头并不代表变量名中不能包含数字呦。
㈣ 等号两边不能有任何空格
[root@MissHou ~]# A =123
-bash: A: command not found
[root@MissHou ~]# A= 123
-bash: 123: command not found
[root@MissHou ~]# A = 123
-bash: A: command not found
[root@MissHou ~]# A=123
[root@MissHou ~]# echo $A
123
㈤ 变量名尽量做到见名知意
NTP_IP=10.1.1.1
DIR=/u01/app1
TMP_FILE=/var/log/1.log
...
说明:一般变量名使用大写(小写也可以),不要同一个脚本中变量全是a,b,c等不容易阅读
5. 变量的定义方式有哪些?
㈠ 基本方式
直接赋值给一个变量
[root@MissHou ~]# A=1234567
[root@MissHou ~]# echo $A
1234567
[root@MissHou ~]# echo ${A:2:4} 表示从A变量中第3个字符开始截取,截取4个字符
3456
说明:
$变量名 和 ${变量名}的异同
相同点:都可以调用变量
不同点:${变量名}可以只截取变量的一部分,而$变量名不可以
㈡ 命令执行结果赋值给变量
[root@MissHou ~]# B=`date +%F`
[root@MissHou ~]# echo $B
2019-04-16
[root@MissHou ~]# C=$(uname -r)
[root@MissHou ~]# echo $C
2.6.32-696.el6.x86_64
㈢ 交互式定义变量(read)
目的:让用户自己给变量赋值,比较灵活。
语法:read [选项] 变量名
常见选项:
选项 | 释义 |
---|---|
-p | 定义提示用户的信息 |
-n | 定义字符数(限制变量值的长度) |
-s | 不显示(不显示用户输入的内容) |
-t | 定义超时时间,默认单位为秒(限制用户输入变量值的超时时间) |
举例说明:
用法1:用户自己定义变量值,即在变量前加read
[root@MissHou ~]# read name
harry
[root@MissHou ~]# echo $name
harry
#在自定义变量时添加提示语句:
[root@MissHou ~]# read -p "Input your name:" name
Input your name:tom
[root@MissHou ~]# echo $name
tom
用法2:变量值来自文件
[root@MissHou ~]# cat 1.txt
10.1.1.1 255.255.255.0
[root@MissHou ~]# read ip mask < 1.txt
[root@MissHou ~]# echo $ip
10.1.1.1
[root@MissHou ~]# echo $mask
255.255.255.0
用法3:位置变量
例如$1/$2...,此时从交互命令行输入多个数值按照定义变量的数字表示索引来决定调用那个位置的数值
㈣ 定义有类型的变量(declare)
目的:给变量做一些限制,固定变量的类型,比如:整型、只读
用法:declare 选项 变量名=变量值
常用选项:
选项 | 释义 | 举例 |
---|---|---|
-i | 将变量看成整数 | declare -i A=123 |
-r | 定义只读变量 | declare -r B=hello |
-a | 定义普通数组;查看普通数组 | |
-A | 定义关联数组;查看关联数组 | |
-x | 将变量通过环境导出 | declare -x AAA=123456 等于 export AAA=123456 |
举例说明:
[root@MissHou ~]# declare -i A=123
[root@MissHou ~]# echo $A
123
[root@MissHou ~]# A=hello
[root@MissHou ~]# echo $A
0
[root@MissHou ~]# declare -r B=hello
[root@MissHou ~]# echo $B
hello
[root@MissHou ~]# B=world
-bash: B: readonly variable
[root@MissHou ~]# unset B
-bash: unset: B: cannot unset: readonly variable
6. 变量的分类
㈠ 本地变量
-
本地变量:当前用户自定义的变量。当前进程中有效,其他进程及当前进程的子进程无效。
定义方式:变量名=变量值
查看进程父子关系 [ipnet@localhost ~]$ ps -auxf |grep bash ipnet 19447 0.0 0.0 115440 2000 pts/0 Ss 10:29 0:00 \_ -bash ipnet 20741 0.0 0.0 115440 1984 pts/1 Ss 10:43 0:00 \_ -bash root 20844 0.0 0.0 115440 2008 pts/1 S 10:44 0:00 | \_ -bash ipnet 22356 0.0 0.0 115440 2028 pts/2 Ss 11:14 0:00 \_ -bash ipnet 27420 0.0 0.0 115440 1984 pts/2 S 23:50 0:00 | \_ bash ipnet 27448 0.0 0.0 112708 948 pts/2 S+ 23:50 0:00 | \_ grep --color=auto bash ipnet 23420 0.0 0.0 115440 2016 pts/3 Ss+ 11:29 0:00 \_ -bash
㈡ 环境变量
- 环境变量:当前进程有效,并且能够被子进程调用。
env
查看当前用户的环境变量set
查询当前用户的所有变量(临时变量与环境变量)export 变量名=变量值
或者变量名=变量值;export 变量名
[root@MissHou ~]# export A=hello 临时将一个本地变量(临时变量)变成环境变量
[root@MissHou ~]# env|grep ^A
A=hello
永久生效:
vim /etc/profile 或者 ~/.bashrc
export A=hello
或者
A=hello
export A
说明:系统中有一个变量PATH,环境变量
export PATH=/usr/local/mysql/bin:$PATH
㈢ 全局变量
-
全局变量:全局所有的用户和程序都能调用,且继承,新建的用户也默认能调用.
-
解读相关配置文件
文件名 | 说明 | 备注 |
---|---|---|
$HOME/.bashrc | 当前用户的bash信息,用户登录时读取 | 定义别名、umask、函数等 |
$HOME/.bash_profile | 当前用户的环境变量,用户登录时读取 | |
$HOME/.bash_logout | 当前用户退出当前shell时最后读取 | 定义用户退出时执行的程序等 |
/etc/bashrc | 全局的bash信息,所有用户都生效 | |
/etc/profile | 全局环境变量信息 | 系统和所有用户都生效 |
$HOME/.bash_history | 用户的历史命令 | history -w 保存历史记录 history -c 清空历史记录 |
说明:以上文件修改后,都需要重新source让其生效或者退出重新登录。
- 用户登录系统读取相关文件的顺序
/etc/profile
$HOME/.bash_profile
$HOME/.bashrc
/etc/bashrc
$HOME/.bash_logout
㈣ 系统变量
- 系统变量(内置bash中变量) : shell本身已经固定好了它的名字和作用.
内置变量 | 含义 |
---|---|
$? | 上一条命令执行后返回的状态;状态值为0表示执行正常,非0表示执行异常或错误 |
$0 | 当前执行的程序或脚本名 |
$# | 脚本后面接的参数的个数 |
$* | 脚本后面所有参数,参数当成一个整体输出,每一个变量参数之间以空格隔开 |
$@ | 脚本后面所有参数,参数是独立的,也是全部输出 |
$1~$9 | 脚本后面的位置参数,$1表示第1个位置参数,依次类推 |
${10}~${n} | 扩展位置参数,第10个位置变量必须用{}大括号括起来(2位数字以上扩起来) |
$$ | 当前所在进程的进程号,如echo $$ |
$! | 后台运行的最后一个进程号 (当前终端) |
!$ | 调用最后一条命令历史中的参数 |
- 进一步了解位置参数
$1~${n}
#!/bin/bash
#了解shell内置变量中的位置参数含义
echo "\$0 = $0"
echo "\$# = $#"
echo "\$* = $*"
echo "\$@ = $@"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$11 = ${11}"
echo "\$12 = ${12}"
- 进一步了解$*和$@的区别
$*
:表示将变量看成一个整体
$@
:表示变量是独立的
#!/bin/bash
for i in "$@"
do
echo $i
done
echo "======我是分割线======="
for i in "$*"
do
echo $i
done
[root@MissHou ~]# bash 3.sh a b c
a
b
c
======我是分割线=======
a b c
7.变量上的操作
1.变量删除
2.变量索引及切片
3.变量内容替换
4.变量内容替代
${-}
号的作用
${:-}
的作用
${+}
,${:+}
,${=}
,${:=}
,${?}
,${:?}
的作用