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%%.*}
*************** 当你发现自己的才华撑不起野心时,就请安静下来学习吧!***************
原文地址:https://www.cnblogs.com/lvzhenjiang/p/14199117.html