shell之变量
目录
一、变量
一句话概括:变量就是用来临时保存数据的,该数据可以是变化的数据。
变量的使用场景:
- 如果某个内容需要被多次使用,并且在代码中重复出现,那么就应该考虑使用使用变量来代表该内容,这样在修改内容的时候,仅仅需要修改变量的值即可;
- 在代码运行的过程中,可能会把某些命令的执行结果保存起来,后续代码需要使用这些结果,就可以直接使用这个变量;
1.1 定义变量
$ A=hello 定义变量
$ echo $A 调用变量
hello
$ echo ${A} 调用变量的另一种方法
hello
$ A=world 即使变量已经赋值,也可再次被赋值
$ echo $A 调用变量,第二次的值会覆盖第一次的值
world
$ unset A 取消变量
$ echo $A 调用变量
1.2 变量的定义规则
1)变量名称严格区分大小写
$ A=hello
$ a=world
$ echo $A
hello
$ echo $a
world
2)变量名称不可有特殊符号
$ *A=hello
-bash: *A=hello: command not found
$ ?A=hello
-bash: ?A=hello: command not found
$ @A=hello
-bash: @A=hello: command not found
特别说明:对于有空格的字符串给变量赋值时,要用引号引起来
$ A=hello world
-bash: world: command not found
$ A="hello world"
$ A='hello world'
3)变量名称不能以数字开头
$ 1A=hello
-bash: 1A=hello: command not found
$ A1=hello
$ echo $A1
hello
注意:不能以数字开头并不代表变量名中不能包含数字
4)等号两边不能有空格
$ A =123
-bash: A: command not found
$ A= 123
-bash: 123: command not found
$ A = 123
-bash: A: command not found
$ A=123
$ echo $A
123
5)变量名称应尽量做到见名知意
NTP_IP=10.1.1.1
DIR=/u01/app1
TMP_FILE=/var/log/1.log
...
说明:一般变量名使用大写(小写也可以),不要同一个脚本中变量全是a,b,c等不容易阅读
1.3 变量的定义方式
1)基本方式
$ A=1234567
$ echo $A
1234567
$ echo ${A:2:4} 表示从A变量中第3个字符开始截取,截取4个字符
3456
说明:
$变量名 和 ${变量名}的异同
相同点:都可以调用变量
不同点:${变量名}可以只截取变量的一部分,而$变量名不可以
2)命令执行结果赋值给变量
$ B=`date +%F`
$ echo $B
2019-04-16
$ C=$(uname -r)
$ echo $C
2.6.32-696.el6.x86_64
3)交互式定义变量
让用户自己给自己的变量赋值,比较灵活。通过read命令来完成!
常见的选项:
- -p:定义提示用户的信息;
- -n:定义字符数(限制变量值的长度);
- -s:不显示(不显示用户输入的内容);
- -t:定义超时时间,默认单位为秒(限制用户输入变量值的超时时间);
用法1:用户自己定义变量值
$ read name
harry
$ echo $name
harry
$ read -p "Input your name:" name
Input your name:tom
$ echo $name
tom
用法2:变量值来自文件
$ cat 1.txt
10.1.1.1 255.255.255.0
$ read ip mask < 1.txt
$ echo $ip
10.1.1.1
$ echo $mask
255.255.255.0
4)定义有类型的变量
给变量做一些限制,固定变量的类型,比如:整型、只读……。通过declare来实现!
常用的选项:
- -i:将变量设置为整数;
- -r:定义只读变量;
- -x:指定的变量会成为环境变量,可供shell以外的程序来使用;
$ declare -i A=123
$ echo $A
123
$ A=hello
$ echo $A
0
$ declare -r B=hello
$ echo $B
hello
$ B=world
-bash: B: readonly variable
$ unset B
-bash: unset: B: cannot unset: readonly variable
1.4 变量的分类
1)本地变量
当前用户自定义的变量,当前进程中有效,其他进程及当前进程的子进程无效!
2)环境变量
当前进程有效,并且可以被子进程调用!
- env:查看当前用户的环境变量;
- set:查询当前用户的所有变量(临时变量与环境变量);
$ export A=hello 临时将一个本地变量(临时变量)变成环境变量
$ env|grep ^A
A=hello
export 变量名=变量值 或者 变量名=变量值;export 变量名
永久生效:
vim /etc/profile 或者 ~/.bashrc
export A=hello
或者
A=hello
export A
说明:系统中有一个变量PATH,环境变量
export PATH=/usr/local/mysql/bin:$PATH
3)全局变量
所有的用户和程序都可以调用,且继承,新建的用户默认情况也可调用!
全局变量相关的配置文件:
文件名 | 说明 |
---|---|
$HOME/.bashrc | 当前用户的bash信息,用户登录时读取 |
$HOME/.bash_profile | 当前用户的环境变量,用户登录时读取 |
$HOME/.bash_logout | 当前用户退出当前shell时最后读取 |
/etc/bashrc | 全局的bash信息,所有用户都生效 |
/etc/profile | 全局环境变量信息 |
$HOME/.bash_history | 用户的历史命令 |
以上文件进行修改后,需重新使用source使其生效或退出重新登录。
用户登录系统读取相关文件的顺序:
1)/etc/profile
2)$HOME/.bash_profile
3)$HOME/.bashrc
4)/etc/bashrc
5)$HOME/.bash_logout
4)系统变量
系统内置的变量:
内置变量 | 含义 |
---|---|
$? | 上一条命令执行后返回的状态;状态值为0表示执行正常,非0 #F44336表示执行异常或错误 |
$0 | 当前执行的程序或脚本名 |
$# | 脚本后接的参数的个数 #F44336 |
$* | 脚本后面所有参数 #F44336,参数当成一个整体输出,每一个变量参数之间以空格隔开 |
$@ | 脚本后面所有参数 #F44336,参数是独立的,也是全部输出 |
$1~$9 | 脚本后面的位置参数 #F44336,$1表示第1个位置参数,依次类推 |
${10}~$n | 展位置参数,第10个位置变量必须用{}大括号括起来(2位数字以上扩起来) |
$$ | 当前所在进程的进程号,如echo $$ |
$! | 后台运行的最后一个进程号 (当前终端) |
!$ | 调用最后一条命令历史中的参数 #F44336 |
进一步了解位置参数$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
$ bash 3.sh a b c
a
b
c
======我是分割线=======
a b c
二、简单四则运算
默认情况下,shell就只能支持简单的整数运算!
2.1 四则运算符号
表达式 | 举例 |
---|---|
$(()) | echo $((1+1)) |
$[ ] | echo $[10-5] |
expr | expr 10 / 5 |
let | n=1;let n+=1 等价于 let n=n+1 |
2.2 了解i++和++i
对变量的值的影响
$ i=1
$ let i++
$ echo $i
2
$ j=1
$ let ++j
$ echo $j
2
对表达式的值得影响
$ unset i j
$ i=1;j=1
$ let x=i++ 先赋值,再运算
$ let y=++j 先运算,再赋值
$ echo $i
2
$ echo $j
2
$ echo $x
1
$ echo $y
2
三、数组
3.1 数组定义
1)数组分类
- 普通数组:只能使用整数作为数组索引;
- 关联数组:可以使用字符串作为数组索引;
2)普通数组定义
一次赋予一个值
数组名[索引下标]=值
array[0]=v1
array[1]=v2
array[2]=v3
array[3]=v4
一次赋予多个值
数组名=(值1 值2 值3 ...)
array=(var1 var2 var3 var4)
array1=(`cat /etc/passwd`) 将文件中每一行赋值给array1数组
array2=(`ls /root`)
array3=(harry amy jack "lzj")
array4=(1 2 3 4 "hello world" [10]=linux)
3)数组的读取
${数组名[元素下标]}
echo ${array[0]} 获取数组里第一个元素
echo ${array[*]} 获取数组里的所有元素
echo ${#array[*]} 获取数组里所有元素个数
echo ${!array[@]} 获取数组元素的索引下标
echo ${array[@]:1:2} 访问指定的元素;1代表从下标为1的元素开始获取;2代表获取后面几个元素
查看普通数组信息:
$ declare -a
4)关联数组定义
①首先声明关联数组
declare -A asso_array1
declare -A asso_array2
declare -A asso_array3
②数组赋值
- 一次赋一个值
数组名[索引or下标]=变量值
# asso_array1[linux]=one
# asso_array1[java]=two
# asso_array1[php]=three
- 一次赋多个值
# asso_array2=([name1]=harry [name2]=jack [name3]=amy [name4]="lzj")
- 查看关联数组
# declare -A
declare -A asso_array1='([php]="three" [java]="two" [linux]="one" )'
declare -A asso_array2='([name3]="amy" [name2]="jack" [name1]="harry" [name4]="lzj" )'
- 获取关联数组值
# echo ${asso_array1[linux]}
one
# echo ${asso_array1[php]}
three
# echo ${asso_array1[*]}
three two one
# echo ${!asso_array1[*]}
php java linux
# echo ${#asso_array1[*]}
3
# echo ${#asso_array2[*]}
4
# echo ${!asso_array2[*]}
name3 name2 name1 name4
- 其他定义方式
$ declare -A books
$ let books[linux]++
$ declare -A|grep books
declare -A books='([linux]="1" )'
$ let books[linux]++
$ declare -A|grep books
declare -A books='([linux]="2" )'
3.2 其他变量定义
- 取出一个目录下的目录和文件:dirname和 basename
# A=/root/Desktop/shell/mem.txt
# echo $A
/root/Desktop/shell/mem.txt
# dirname $A 取出目录
/root/Desktop/shell
# basename $A 取出文件
mem.txt
- 变量"内容"的删除和替换
一个“%”代表从右往左去掉一个/key/
两个“%%”代表从右往左最大去掉/key/
一个“#”代表从左往右去掉一个/key/
两个“###”代表从左往右最大去掉/key/
举例说明:
# url=www.taobao.com
# echo ${#url} 获取变量的长度
# echo ${url#*.}
# echo ${url###*.}
# echo ${url%.*}
# echo ${url%%.*}
*************** 当你发现自己的才华撑不起野心时,就请安静下来学习吧!***************