Bash中的变量

变量和运算符

bash 中的变量和运算符

变量即可以变化的量 —— 存放数据的容器

  • 常量 —— 不会变化的数值

变量的定义准则 —— 变量的命名规范

  • 变量名称可以由字母、数字和下划线组成
  • 不能以数字开头,变量中间不能有空格 —— “2name”,错误示范

注:变量的值如果有空格,需要使用单引号或双引号包括 —— 如 test=“hello world”

变量的分类

  • 自定义变量 —— 自己创建的变量,注意命名规范
  • 数值变量 —— 需要单独声明类型,用于保存数值型数据,默认保存的数值是字符型
    • 数组变量 —— 保存多个同类型的数据
  • 环境变量 —— 根据登录环境的不同使用不同的值
  • 预定义变量 —— $?
  • 位置参数变量

变量的声明方式

  • 变量名=值
  • read -p “提示词” 变量名
  • echo -n “提示词” ; read 变量名

变量的调用

  • echo ${变量名} —— 大括号可以表示括号内的字符是一个整体

数值运算器:

  • echo $((运算式))
  • echo $[运算式]

注:小括号和中括号的数值运算器作用相同,但都只能进行整数运算

例1:在 Bash 中变量的默认类型都是字符串型,若要进行数值运算必须修改变量类型为数值型

x=666 ; y=888 ; s=$x+$y ; echo $s			#输出结果:666+888
x=666 ; y=888 ; s=$(($x+$y)) ; echo $s		#对比结果:1554

例2:编写一个简单功能的计算器

#需求分析
# 1. 基本的加减乘除能实现
# 2. 两个数值间的运算
# 3. 可以自定义数值和运算符号
#!/bin/bash
echo -n "请输入要计算的第一个数值:"
read x
echo -n "请输入要计算的运算符(+ - * /)"
read y
echo -n "请输入要计算的第二个数值:"
read z
echo $(($x$y$x))

例3:对例2 编写的计算器脚本进行进一步升级

#!/bin/bash
echo -n "请输入要计算的运算式:"
reax x
echo $(($x))

写脚本的思路:

  1. 需求分析 & 素材整理
    • 手动执行该任务所需的所有素材:命令、目录、文件、权限、、、
    • 执行步骤
  2. 构建脚本
    • 先构建骨架 —— 大致的功能
    • 功能测试
    • 然后再给每一个步骤添加单独的功能

例1:编写一个脚本,自动配置本地 yum 源

#!/bin/bash
#mount /dev/sr0 /media/
[ -b /dev/sr0 ] && mount /dev/sr0 /media/ || echo "sr0不存在"
cd /etc/yum.repos.d/
mkdir bak
mv C* bak
echo "[CentOS]
name=xxx
baseusrl=file:///media/
enable=yes
gpgcheck=0" >> CentOS-Media.repo

说明:先写出大致框架,然后再对脚本进行完善 —— 加入了对本地介质,sr0 的判断

例2:生成随机字符,然后使用 tr 和 cut 进行过滤截取

read -p "请输入要生成密码的长度:" len			# 接受键盘输入
read -p "请输入要生成密码的个数:" num			# 并定义变量取值
pass=$(head -5 /dev/urandom | tr -dc a-zA-Z0-9\@\_\(\-\* | cut -c 1-$len)
echo $pass

注:read 命令可以接受用户的键盘输入,-p 是输出提示语句,tr -dc 是过滤字符,cut -c 是截取字符范围

数值变量

普通变量默认都是字符串

x=100 ; y=200 ; sum=$x+$y		#结果是 100+200,"+" 表示字符串的连接

例1:将 sum 声明成数值型,即可运算

x=100 ; y=200
declare -i sum=$x+$y			#结果是 300,使用 declare 可声明任意类型的变量

例2:运算式格式,对变量进行运算

x=100 ; y=200
sum=$(($x+$y)) ; echo sum		#结果是 300,使用 $(()) 的方式进行变量运算

declare —— 声明变量的命令

  • declare -p 变量 —— 查看变量类型
  • declare -x 变量 —— 声明环境变量,作用同 export
    • 环境变量会根据用户身份的不同而修改变量的值
  • declare -i 变量 —— 声明数值变量
  • declare -r 变量 —— 声明只读变量,r = ro
    • 只读变量只能进行调用,不能进行修改和删除,也不能取消只读选项

例:只读变量

declare -r test=100w ; echo $test			# 输出 100w,可以调用
test=200w			# 只读变量,不可修改
unset test			# 只读变量,不可取消
declare +r test		# 取消变量的只读选项

注:变量退出终端,即会消失,这样设置的变量都是临时性的

补:env —— 查看所有环境变量,set —— 查看所有变量,unset —— 取消一个变量

使用 expr 或 let 进行运算 —— 其它运算工具

  • 直接声明运算过程是数值运算,而不是通过声明变量的类型 —— 相对简单

例1:expr —— 注意格式

x=100 ; y=200
expr $x + $y				#直接输出 300,一定要注意 "+" 两端要有空格,否则是字符串连接

注:expr 使用时需要注意的是,在运算符两边要有空格,否则不会正常运算

例2:let 相对简单易用,原理相同 —— 注意格式变化

x=1000 ; y=2000
let z=$x+$y ; echo $z			# 输出运算后的结果 3000

注:let 还能进行自增自减,或者指定增加量或减少量

例3:使用 let 进行自增、自减运算

n=1 ; echo $n				# 需要对 n 进行自增
let n++ ; echo $n			# 使用 let n++ 让 n 自增 1
let n+=1 ; echo $n			# 使用 "+="、"-=" 方式自增

说明:+=、-=、*=、/= —— 表示 n = n + 、n = n -、、、

常用运算符

shell 常用运算符

优先级运算符功能描述
1+、-正、负
2*、/、%乘、除、取余
3+、-加、减
4+=、-=、、、自增、自减、、、

运算符是有优先级别的

例:取余运算

echo $((14%3))		# 2
echo $((-14%3))		# -2
echo $((14%-3))		# 2
echo $((-14%-3))	# -2

注:取余运算的符号,取决于被除数,前面的那个数

补:RANDOM —— 生成随机数的环境变量,配合取余运算

echo $(($RANDOM%100))		# 取 0-99 的随机数
echo $(($RANDOM%100+1))		# 取 1-100 的随机数

注:对 100 取余,可以代表是要取 100 的数,小于 100 的数,所以是 0-99

扩展 —— 取模运算

  • 其他语言中除了取余之外,还有取模运算
    1. 求整数商:c = a / b
    2. 计算模或者余数:r = a - c * b

注意:当 a 和 b 符号一致时,求模运算和求余运算所得的 c 的值一致,因此结果一致

  • 但是当符号不一致的时候,结果不一样,具体来说
  • 求模运算结果的符号和 b 一致,求余运算结果的符号和 a 一致

注:shell 并不支持取模运算,所以了解即可

逻辑与

echo $((0&&0))			# 0
echo $((0&&1))			# 0
echo $((1&&0))			# 0
echo $((1&&1))			# 1

逻辑运算,逻辑与有零则零,全一为一,逻辑或有一则一,全零为零

变量叠加

变量叠加

  • PATH —— 命令所在路径的环境变量
    • echo $PATH —— 输出环境变量
  • PATH=$PATH:/bash —— 在原有基础上叠加一个 /bash 目录

例:不同用户的 PATH 环境变量的值是不同的

# root 用户
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
# 普通用户
[nc1239@localhost ~]$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/nc1239/.local/bin:/home/nc1239/bin

说明:

  1. 若是用户的家目录中有 /bin 目录,则在命令查找路径范围之中
  2. 超级用户可以执行任何命令,所以超级用户的命令搜索路径排序可以任意
  3. 普通用户没有权限执行 /usr/local/sbin 中的命令,所以普通用户 /usr/local/bin 目录要排在前面

问:为什么不同的用户同一个变量,含有不同的结果?—— 环境变量的特点

  • 环境变量:根据登录环境的不同使用不同的值

将自己编写的脚本变成可执行的命令 —— 两种方式

  1. 将脚本放在命令的搜索路径,让系统可以找到 —— 将脚本放在 PATH 环境变量的范围
  2. 让 PATH 环境变量包含,我们自己创建的脚本目录 —— 扩展 PATH 环境变量的范围,变量叠加的体现

对 PATH 环境变量做变量结果的叠加 —— 不破坏原有的值,在原有基础上追加新值

  • PATH=$PATH:/bash —— 原值不变,增加了一个新值

如此:根目录下的 “/bash” 目录中的脚本都可以以执行命令一样方式执行

例:各个用户家目录的 “.bashrc” 文件

# User specific environment
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
then
	PATH='$HOME/.local/bin:$HOME/bin:$PATH'				# 变量叠加
fi
export PATH

说明:不管什么用户,都是在原有的四个基础目录,叠加的用户家目录下的目录 —— 系统提供的叠加方案

注:CentOS 7 变量叠加是在 ~/.bash_profile 文件中定义的

环境变量

补充:umask —— 权限掩码

# 该段代码的作用是判断用户创建文件时使用的掩码值
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`"]
then
	umask 002	# 如果用户 UID 大于 199,并且用户名和组名相同,使用 002 掩码
	UMASK=002		# 在原有基础上,创建一个变量 UMASK=002
else
	umask 022	# 否则 umask 值默认 022
	UMASK=022		# 在原有的基础上,创建一个变量 UMASK=022
fi

说明:定义了环境变量 UMASK,可以通过 echo $UMASK 的方式得到环境变量的值

环境变量

  • 同一个系统内,根据登录用户身份的不同,为同一个变量设置不同值的方式,就叫环境变量

补充:PS1 —— 不是环境变量

  • echo $PS1 --》[\u@\h \W]\$ —— 命令提示符的格式
    • [root@localhost ~]# —— [用户名@hostname where]用户身份类型
    • [nc1239@localhost ~]$ —— 普通用户是 “$”,root 用户是 “#”

注:虽然是不同用户有不同的值,但 PS1 不是环境变量

创建环境变量的条件:

  1. 根据登录环境的不同使用不同的值
  2. 使用特定的命令声明变量的类型

声明环境变量:

  • export PATH=$PATH:/bash —— 这样声明的才叫环境变量
  • PATH=$PATH:/bash --》export PATH —— 两种方式

相关命令

查看变量的命令:

  • set —— 列出当前解析器中所有已加载的变量和函数(所有类型的变量)
  • env —— 仅列出当前解析器中所有已加载的环境变量

例1:使用 set 命令列出所有变量,统计个数

set | more				#分页显示
set | wc -l				#统计个数

例2:使用 env 命令列出所有变量,统计个数

env | wc -l				#统计环境变量个数
env | grep "PA1"		#PA1 不是环境变量,所以找不到
env | grep "PATH"
env | grep "LANG"		#language,语言

删除\取消变量:

  • unset —— 删除或取消变量(所有类型的变量都可以取消)

例:定义变量,再使用 unset 取消变量

num1=100; echo $num1; set | grep num1
unset num1; set | grep num1; echo $num1

说明:“_” 用于保存上次被调用过的变量名称

判断变量类型:

  • declare -p PATH —— 查看变量类型

说明:

  • -x —— 环境变量
  • – —— 普通变量,字符

问:整数类型变量的变量类型用什么表示?—— -i

声明变量 —— 不同类型

  • declare —— 声明变量,指定类型
    • -x —— 声明环境变量,和 export 是同样的效果
    • -i —— 声明整数型变量

例:声明整数型变量

declare -i num1=100
declare num2=200
declare -p num1 		# declare -i num1="100"
declare -p num2			# declare -- num2="200"

位置参数变量

例1:编写一个脚本

[root@localhost ~]# cat 3.sh 
#!/bin/bash
echo "$1"						# $1 是一个整体,类似 $?
[root@localhost ~]# ./3.sh nc1239
nc1239							# 直接输出

注:$1 的作用是调用脚本外的第一个值

例2:改变一下

[root@localhost ~]# cat 3.sh 
#!/bin/bash
echo "$(($1))"					# 如此,可以进行运算式的运算
[root@localhost ~]# ./3.sh 1+2+3+4
10								# 输出计算结果

例3:对比,和之前的运算器脚本

[root@localhost ~]# cat 1.sh 2.sh 3.sh 
#!/bin/bash
echo -n "请输入要计算的第一个数值:"
read x
echo -n "请输入要计算的运算符(+ - * /)"
read y
echo -n "请输入要计算的第二个数值:"
read z
echo $(($x$y$z))										# 1.sh

#!/bin/bash
echo "请输入运算式:"
read x;echo $(($x))										# 2.sh

#!/bin/bash
echo $1												# $1 变量

例4:位置参数变量 —— 位置参数变量的格式

  • vim 4.sh

    #!/bin/bash
    echo $1
    echo $3
    echo $5
    echo $10
    echo ${10}
    
  • 测试1

    [root@localhost ~]# ./4.sh 1 2 3 4 5 6 7 8 9 10
    1
    3
    5
    10										# 问题位置
    10
    
  • 测试2

    [root@localhost ~]# ./4.sh a b c d e f g h i j k
    a
    c
    e
    a0										# 发现问题
    j
    
  • 实际上,$10 调用的是第一个值,然后加上了一个 0,两位的数字必须加上大括号 {}

位置参数变量

  • 按参数排列位置,调用参数,所以叫做位置参数变量
    • $n —— 代表脚本后的第几个值
    • $0 —— 代表脚本本身,代表调用的是脚本的名字,第 0 个,也就是调用脚本的字符串
    • $@ —— 将所有参数逐个,依次调用
    • $* —— 将所有参数当作一个整体调用
    • $# —— 统计输入的参数个数

例1:对比不同位置参数变量的区别

  • 对比:

    #!/bin/bash
    echo "$1"
    echo "$3"
    echo "$5"
    
    echo "$0"
    echo "$@"
    echo "$*"
    
  • 测试:

    [root@localhost ~]# ./4.sh a b c d e f
    a
    c
    e
    ./4.sh					# $0
    a b c d e f				# $@
    a b c d e f				# $*
    

注:位置参数变量的 $0 表示的是调用过程中的第 “1” 个,即脚本自己本身的名字

例2:循环结构,使用 $@ 对输入的参数逐个调用

  • vim 5.sh --》chmod +x 5.sh

    #!/bin/bash
    
    echo "您一共输入了 $# 个值"				# $# 统计的参数个数就是循环次数
    
    n=1
    for i in "$@"												#将每一个值取出,赋值给 i
    do
    	echo "第 $n 个位置的值是:$i"								#将 i 的值依次输出
    	let n=n+1								# n 用于计数
    done
    
  • 测试

    [root@localhost ~]# ./5.sh 1 2 3 4 5
    您一共输入了 5 个值
    第 1 个位置的值是:1
    第 2 个位置的值是:2
    第 3 个位置的值是:3
    第 4 个位置的值是:4
    第 5 个位置的值是:5
    

例3:使用 $* 将所有参数当作一个整体输出 —— 只当作了一个字符串

  • 修改其中一行:

    for i in "$*"
    
  • 对比 $@

    [root@localhost ~]# ./5.sh 1 2 3 4 5
    您一共输入了 5 个值
    第 1 个位置的值是:1 2 3 4 5
    

注:$@ 和 ∗ 都是将脚本后的所有值,保存并输出,但过程不同, * 都是将脚本后的所有值,保存并输出,但过程不同, 都是将脚本后的所有值,保存并输出,但过程不同,* 是将所有参数当做整体,$@ 是一个一个传递,独立单独的个体

总结 —— 位置参数变量

  • $n —— 代表脚本后的第一几个值
  • $0 —— 代表脚本本身
  • $@ —— 依次保存传递值
  • $* —— 将所有值保存为一个整体,即一个值
  • $# —— 统计脚本后值的数量

预定义变量

预定义变量

  • $? —— 最后一次执行的命令返回状态
    • 如果这个变量的值为 0,证明上一个命令正确执行
    • 如果这个边的值为非 0,则证明上一个命令执行不正确(具体是什么数字由命令本身决定)
  • $$ —— 当前进程的进程号,PID
  • $! —— 后台运行的最后一个进程的进程号,PID

例1:编写自动配置本地 yum 源的脚本 —— 判断语句,自定义错误提示以及 $? 收集错误提示

  • vim a.sh --》chmod +x a.sh

    #!/bin/bash
    [ ! -b /dev/sr1 ] && exit 23			# 若sr1不存在,则退出,提示 23
    # 注:-b可判断块设备文件是否存在,!将结果取反,所以是不存在则为真,sr1不存在,就提示错误信息 23
    
  • 测试:echo $?

    [root@localhost ~]# ./a.sh 
    [root@localhost ~]# echo $?
    23
    

综上:echo $? —— 这条语句,给出的报错数字是可以自己定义的

例2:编写自动配置本地 yum 源的脚本 —— 完善

#!/bin/bash
# 第一行声明命令解析器是 /bin/bash
[ -b /dev/sr0 ] && mount /dev/sr0 /media/ || exit 12
# 判断块设备 /dev/sr0 是否存在,存在则挂载,否则提示错误数字 12
cd /etc/yum.repos.d/						#切换到 yum 配置文件目录
[ -d bak ] && echo "目录已存在" || mkdir bak
# 判断目录 bak 是否存在,存在则提示,否则创建 bak,用于保存 yum 配置文件
mv C* bak									#剪切所有 C 开头的文件到 bak 目录
echo "[c7-media]							#使用追加内容的方式,非交互的配置yum
name=CentOS-$releasever - Media
baseurl=file:///mnt
gpgcheck=1
enabled=1									#追加的方式可以创建文件,新建配置文件
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7" >> CentOS-Media.repo

总结 —— 位置参数变量

  • $? —— 最后一次执行的命令返回状态
  • $$ —— 当前进程的进程号,PID
  • $! —— 后台运行的最后一个进程的进程号,PID
  • 13
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值