什么是变量

#变量即变化的量,核心是“变”与“量”二字,变即变化,量即衡量状态。
    量:是记录现实世界当中的某种状态
    变:指的是记录的状态是可以发生变化的

为什么使用变量

#程序执行的本质就是一系列状态的变化,变是程序执行的直接体现,所以我们需要有一种机制能够反映或者说是保存下来程序执行时状态以及状态的变化。是为了让计算机能够像人一样去将一个事物的状态记忆下来(存到计算机内)
`存` ,永远不是目的。
目的是为了, `取`
让计算机以后在使用的时候,可以取出来。

如何使用变量?

#先定义一个变量
[root@xbs ~]# name=jiujiu
[root@xbs ~]# echo name
name
[root@xbs ~]# echo $name
jiujiu
#由上可得知在调用变量得时候,没有使用$时,变量名原文输出;使用$符号时,调取到了变量值

#定义变量的语法
1)变量名
相当于一个门牌号,便于取出变量值,是访问到值的唯一方式
2)赋值符号
将值的内存地址,绑定给变量名
3)变量值
用来表示状态
变量的使用规则:先定义,在通过变量名去引用。
#变量名的命名规则:
1.大前提:变量名的命名应该能够反映出值记录的状态。
2.变量是用来访问变量值的,所以变量名应该遵循一定规范,来方便我们标识存到内存中值的功能。
1.变量名只能是 字母、数字或下划线的任意组合(区分大小写)
例如:
x=1
X=2
是两个变量
2.变量名的第一个字符不能是数字
例如:
1x=1
123_x=1
3.尽量不要使用命令设置变量
例如:[echo,ls,cd,pwd...]
# 定义变量名的方式 示例:
# 1.下划线+纯小写英文
[root@web02 ~]# name_of_wb='wangbiao'
[root@web02 ~]# echo $name_of_wb
wangbiao
# 2.驼峰体
[root@web02 ~]# #Name_Of_hj=123
[root@web02 ~]# #NameOfI=456
# 3.下划线+纯大写
[root@web02 ~]# NAME_OF_HHH='heiheiehi'
# 4.不推荐使用的方式
1)变量名为中文、拼音
2)变量名过长
3)变量名词不达意

环境变量

# 查看系统环境变量
env
export
declare
-----------------------------------------------------------------------------------------------------
1. env命令:
- 作用:env命令是一个外部命令,用于显示当前环境的所有变量,包括环境变量和用户定义的变量。
- 使用:在命令行中直接输入`env`,即可显示所有环境变量的键值对。
2. export命令:
- 作用:export命令用于设置或显示环境变量,可以将当前Shell的变量导出为全局环境变量,使其对子进程可见。
- 使用:在命令行中,可以使用`export <变量名>=<值>`的方式来设置环境变量。同时,也可以使用`export <变量名>`来显示已经设置的某个环境变量的值。
3. declare命令:
- 作用:declare命令用于声明和设置变量的属性,包括环境变量、局部变量、数组、函数等。
- 使用:在Shell脚本中,可以使用`declare`命令来声明和设置变量的属性,例如`declare -x <变量名>=<值>`用于声明并导出环境变量。
# 环境变量 (重点记住)
LANG //字符集语言 LANG=zh_CN.UTF-8
PATH //该变量中的路径里的所有可执行文件,都可以直接执行不需要加路径
PS1 //命令提示符
UID //当前登录用户的UID
HOSTNAME //当前主机名
PWD //当前工作路径
USER // 当前登录的用户
# (历史命令了解即可)
HISTSIZE //历史命令显示行
HISTFILESIZE //历史命令保存文件保存的行数
HISTFILE //历史命令保存的路径
TMOUT //设置超时时间 超过设置的时间就退出
HISTCONTROL: export HISTCONTROL=ignorespace
# 任何命令前面加空格不会被history追踪到
PROMPT_COMMAND # 跳板机专用变量

普通变量

局部变量,在脚本中自定义的变量

DATE=$(date +%F-%T)
IP=$(ifconfig eth0|awk 'NR==2{print $2}')

mkdir $DATE_$IP_$HOSTNAME ## 基本凉了

### 注意使用大括号分隔变量
mkdir ${DATE}_${IP}_${HOSTNAME}

# 与环境变量相关的文件
/etc/profile
/etc/bashrc
~/.bashrc
~/.bashrc_profile
/etc/profile.d/*.sh

特殊变量介绍

匹配脚本参数,服务状态,特殊替换(重点)
应用场景:
1.提高书写脚本及脚本执行效率
2.判断服务状态、脚本参数、删除、替换
符号 含义 应用
$0 脚本名字 脚本使用方法常用:给出错误提示或者使用帮助
$n 脚本的第N个参数 命令传参,传递给脚本,在脚本中使用
$# 统计脚本参数的个数 判断脚本是否传参
$* 获取脚本所有的参数 将所有参数当成是一个整体,对传递的参数进行判断
$@ 获取脚本所有的参数 将每一个参数当成是一个整体,对传递的参数进行判断
#$* 1.不适合数组使用,调用使用的双引 //接受脚本后的所有的参数
$@ 1.适合后面数组数据类型使用 调用用双引 //接受脚本后的所有的参数
竖着看 $@
横着看 $*

示例

1)$? :脚本执行返回值

脚本控制返回值的用法,这个脚本执行完毕了,会返回一个数值,称呼之为返回值,学习shell函数编程以后才能彻底理解,如下只是演示:

[root@hadoop102 ~]# vim jiujiu.sh 
[root@hadoop102 ~]# cat jiujiu.sh 
#!/bin/bash
# $#:取参数总个数  -ne:不等于  2:满足的条件   &&:与(并且)的意思 []:里面是一个条件判断
[ $# -ne 2 ] && {
    echo  "必须是两个参数"  #如果不是2个参数则执行本行代码输出
    exit 110    #终止程序运行。且返回110状态码,提供给当前shell函数的$?变量,若是在函数里,可以用return 110用法
}
echo "输入参数正确" 
[root@hadoop102 ~]# bash jiujiu.sh 15 20 35
必须是两个参数
[root@hadoop102 ~]# echo $?
110
[root@hadoop102 ~]# bash jiujiu.sh 15 20
输入参数正确
[root@hadoop102 ~]# echo $?
0

2)$!:获取上一次后台执行的程序PID

[root@hadoop102 ~]# nohup ping baiduo.com & 1> /dev/null # 让后台运行ping百度,且日志写入/dev/null 
[1] 3182
[root@hadoop102 ~]# nohup: ignoring input and appending output to ‘nohup.out’

[root@hadoop102 ~]# ps -ef | grep 3182
root       3182   2586  0 19:18 pts/0    00:00:00 ping baiduo.com
root       3184   2586  0 19:19 pts/0    00:00:00 grep --color=auto 3182
[root@hadoop102 ~]# echo $!
3182

3)$$ :获取当前脚本的PID

[root@hadoop102 ~]# vim jiujiu.sh 
[root@hadoop102 ~]# cat jiujiu.sh 
#!/bin/bash
# $#:取参数总个数  -ne:不等于  2:满足的条件   &&:与(并且)的意思 []:里面是一个条件判断
[ $# -ne 2 ] && {
    echo  "必须是两个参数"  #如果不是2个参数则执行本行代码输出
    exit 110    #终止程序运行。且返回110状态码,提供给当前shell函数的$?变量,若是在函数里,可以用return 110用法
}
echo "输入参数正确" 

echo "当前的脚本id是: $$"
[root@hadoop102 ~]# bash jiujiu.sh 12 25
输入参数正确
当前的脚本id是: 3188
注:脚本PID每次执行都会发生改变

4)$_ :获取上次命令的最后一个参数

[root@hadoop102 ~]# bash jiujiu.sh 12 25
输入参数正确
当前的脚本id是: 3200
[root@hadoop102 ~]# echo $_
25

变量子串(复杂,但实用)

#语法:${#}变量的长度
name=yys
echo ${#name}
name=$1
echo ${#name}
----------------------------------------------------------------------------------------------------
#语法:${变量名:偏移量}
name=web02_yysyys
echo ${name:3:4}

${变量名:偏移量 :            步长}
        从第几个字符开始截取 截取多少个
-----------------------------------------------------------------------------------------------------
#语法:${变量名#字符串} 从变量开头,删除最短匹配word的子串
#语法:${变量名##字符串} 从变量开头,删除最长匹配word的子串
name=/tmp/abdc/1.txt
echo ${name#*/}
echo ${name##*/}
-----------------------------------------------------------------------------------------------------
#语法:${变量名%字符串} 从变量结尾,删除最短匹配word的子串
#语法:${变量名%%字符串} 从变量结尾,删除最长匹配word的子串
name=/tmp/abdc/1.txt
echo ${name%/*}
echo ${name%%/*}
-----------------------------------------------------------------------------------------------------
#语法:${变量名/匹配内容/替换内容}
替换第一个匹配到的字符
#语法:${变量名//匹配内容/替换内容}
替换所有匹配到的字符
read -p '请输入用户名' name
echo ${name/xxx/yyy}
read -p '请输入用户名' name
echo ${name//xxx/yyy}

拓展变量

变量的处理

这四个扩展变量,都属于对变量的值进行判断丶处理

: -

如果parameter变量值为空,返回word字符串

${parameter:-word}

: =

如果para变量值为空,则word替代变量值,且返回其值

${parameter:=word}

: ?

如果para变量值为空,word当作s't'derr输出,否则输出变量值用于设置变量为空导致错误时,返回的错误信息

${parameter:?word}

: +

如果para为空变量为空,什么都不做,否则word返回

${parameter:+word}

实际案例

: -

作用:判断如果变量值为空,就返回后面的字符信息,可以通过result变量去接收
# 变量值为空的情况下
[root@hadoop102 ~]# echo $jiujiu   # 此变量为空

[root@hadoop102 ~]# result=${jiujiu:-hello}   #定义变量名,
[root@hadoop102 ~]# echo $jiujiu   #变量还是为空

[root@hadoop102 ~]# echo $result    #echo result输出变量值
hello
# 变量值不为空的情况
[root@hadoop102 ~]# jiujiu=125
[root@hadoop102 ~]# result2=${jiujiu:-hello}
[root@hadoop102 ~]# echo $jiujiu
125
[root@hadoop102 ~]# echo $result2   #在变量值不为空的情况下,则:-赋值失效
125

:=

作用:如果变量值为空,后面的值,赋值给接收者,以及变量本身
#   变量值为空的前提下
[root@hadoop102 ~]# echo $jiujiu $result
[root@hadoop102 ~]# result=${jiujiu:=hello}
[root@hadoop102 ~]# echo $jiujiu;echo $result
hello
hello
# 变量值不为空的前提下
[root@hadoop102 ~]# echo $jiujiu
hello
[root@hadoop102 ~]# result2=${jiujiu:=daxigaun}
[root@hadoop102 ~]# echo $jiujiu;echo $result2
hello
hello   # 变量值有值的情况下,:=赋值失效  result2取jiujiu的变量值

:?

作用:当变量值为空时,主动输出一个错误信息
# 变量值为空的前提下
[root@hadoop102 ~]# echo ${new_jiujiu}
[root@hadoop102 ~]# echo ${new_jiujiu:?该变量值为空}
-bash: new_jiujiu: 改变量值为空
[root@hadoop102 ~]# new_jiujiu=hello
[root@hadoop102 ~]# echo ${new_jiujiu:?改变量值为空}
hello

:+

作用:当变量为空,什么都不做,否则字符返回个接收者
# 变量值为空的前提下
[root@hadoop102 ~]# echo $jiujiu

[root@hadoop102 ~]# echo ${jiujiu:+hei}

# 变量值不为空的前提下
[root@hadoop102 ~]# jiujiu=hello
[root@hadoop102 ~]# echo ${jiujiu:+hei}
hei   
[root@hadoop102 ~]# like=${jiujiu:+nihao}
[root@hadoop102 ~]# echo $like
nihao

赋值方式

直接赋值,简单粗暴,例: name=jiujiu
间接赋值,我们将一个命令执行的结果赋值给一个变量,例:IP= ifconfig eth0|awk
'NR==2{print $2}'
交互赋值,我们需要跟脚本进行交互,例:read
传参赋值,执行脚本的时候,将需要传递的变量值,写在脚本的后面 $1 $2 $3

交互赋值

read
# -p 打印一句话
    #!/bin/bash
    read -p '请输入用户名' name
    echo ${name//xxx/yyy}
# -s 不显示输入的内容
    #!/bin/bash
    echo "--------注册账号---------"
    read -p "web02 login:" name
    read -ps "passwd:" pas
    len=`echo $pas|awk '{print length()}'`
    if [ $len -lt 8 ];then
        echo '密码必须大于等于8位'
    else
        echo '密码合格'
    fi
# -t 超时时间 超过时间退出脚本
#!/bin/bash
echo "--------注册账号---------"
read -p "web02 login:" name
read -t 5 -ps "passwd:" pas
len=`echo $pas|awk '{print length()}'`
if [ $len -lt 8 ];then
    echo '密码必须大于等于8位'
else
    echo '密码合格'
fi
# -a 将传递的参数以数组去接受

shell的数据类型

  • 字符串
  • 整型
  • 数组
# 字符串赋值
[root@web02 ~]# name=yys

# 取值
[root@web02 ~]# echo $name
yys

# 整型赋值
[root@web02 ~]# age=18
# 取值
[root@web02 ~]# echo $age
18

## 数组类型
# 赋值
[root@web02 ~]# list=(python java golong shell)
[root@web02 ~]# list[0]='abc'
[root@web02 ~]# list[1]='efg'
[root@web02 ~]# list[2]='hij'
[root@web02 ~]# list[3]='lnm'

# 取值
[root@web02 ~]# echo ${list[0]}
python
[root@web02 ~]# echo ${list[1]}
java
[root@web02 ~]# echo ${list[2]}
golong
[root@web02 ~]# echo ${list[3]}
shell
0