shell编程之变量定义

Posted 锦衣admin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell编程之变量定义相关的知识,希望对你有一定的参考价值。

变量介绍

计算机中的单位:
	1B = 8b
	1KB = 1024B
	1MB = 1024KB
	1GB = 1024MB
	1TB = 1024GB
	1PB = 1024TB
	1EB = 1024TB

	b:是计算机内部数据储存的最基本单位(bit 位)
	B:计算机中数据处理的基本单位,计算机中以字节为单位存储和解释信息(byte 字节)

cpu读取数据时的操作:

  • 读:计算机将数据从硬盘读出存入内存,再从内存读出给CPU

  • 写:CPU将数据存入内存,内存再将数据存入硬盘

变量介绍:

在编程中,我们总有一些数据需要存放在内存中,以待后续使用时快速读取。变量是编程中最常用的一种临时在内存中存取数据的一种方式

变量相当于一个容器,用于存放数据,变量有两个地址:

  • 逻辑地址:变量的名称(PATH)

  • 物理地址:内存中的块地址(0x05),数据存放的地方

变量的作用:临时在内存中存取数据,提升计算机的执行效率

变量存取原理:

关于内存的说明:
	系统启动		=>	内存被按照1B一个单位划分成N块,并且以十六进制为每一个块空间编号

	内存跟踪表	=>	使用和未使用内存空间的地址编号

	内存申请		=>	系统从未使用的内存中拿出一块或者一段连续的空间给用户使用,同时在内存跟踪表中
					记录该地址被占用,不再分给别的用户使用,同时在系统中建立映射关系、
					如变量名:STRING1 < == > 0x5(ABC)
							

	释放内存		=>	从跟踪表中删除映射记录,下次存数据直接覆盖原块空间

在这里插入图片描述

变量定义

什么时候需要定义变量?

  • 如果某个内容需要多次使用,并且在代码中重复出现,那么就可以用变量代替该内容。这样在修改内容的时候,仅仅需要修改变量的值

  • 在代码运作过程中,可能会把某些命令的执行结果保存起来,后续代码需要使用这些结果,就可以直接使用这个变量

定义一个变量:

变量格式:变量名=变量值

在shel编程中,变量名和等号之间不能有空格

变量命名规则:

变量命名规则:
	命名只能使用英文字母、数字和下划线,首字母不能数字开头
	中间不能有空格,可以使用下划线。如:_name='abc'

	不能使用标点符号
	不能使用bash里的关键字(可用"help"命令查看保留关键字)

#l	注意:字符串要用单引号或双引号引起来;建议变量名为大写,和命令区分

变量的定义与取消:

"定义变量":变量赋值,此种方法设置本地变量
	# xjj='hello'		=>	定义一个变量命令为xjj,值为hello的本地变量
		[root@server ~]# xjj='hello'
		[root@server ~]# echo $xjj		=>	需要$符号取变量值内容
			hello

	备注:定义变量会占用内存空间,除非重启系统释放内存或"unset"取消变量,否则这个变量会一直占用内存的空间
		 就算你关闭当前定义变量的这个shell,这个变量占用的内存空间也不会释放,删除的只是内存跟踪表的映射记录,
		但是内存数据没有删除,还是会占用内存空间,这时候想使用这个内存空间除非是重新覆盖变量的值或者是unset取消变量 
				


"取消变量":取消当前环境中的变量(释放内存),如果变量保存在文件中,下次重启又会恢复
	# unset xjj			=>	通过"unset"命令取消当前环境的变量
		[root@server ~]# echo $xjj
			hello
		[root@server ~]# unset xjj
		[root@server ~]# echo $xjj		=>	变量没有了

变量类型:delcare命令

变量类型:
	命令格式:
		# declare [选项] 变量=
			选项说明:
				-i:将变量类型限定为整数
				-r:使变量只读readnoly,该变量的值无法改变,并且不能"unset"取消变量
				-x:标记变量通过环境导出,export(即环境变量)
				-a:指定索引数组(普通数组);查看普通数组
				-A:指定为关联数组;查看关联数组
	



演示:
	# declare -i age		=>	-i 选项限定变量的类型为整数
		[root@server ~]# age=13
		[root@server ~]# echo $age
			13
		[root@server ~]# declare -i age
		[root@server ~]# age=13.5		=>	不能修改为浮点数类型
			-bash: 13.5: syntax error: invalid arithmetic operator (error token is ".5")
		[root@server ~]# age=11			=>	可以修改为其他整数
		[root@server ~]# echo $age
			11

	# declare -r Pi=3.14		=>	-r 选项限定变量的值
		[root@server ~]# declare -r Pi=3.14
		[root@server ~]# Pi=123
			-bash: Pi: readonly variable
		[root@server ~]# unset Pi		=>	无法取消变量
			-bash: unset: Pi: cannot unset: readonly variable

变量分类

系统中的变量根据作用域及生命周期可以分为四类:本地变量环境变量全局变量内置变量

本地变量

当前用户自定义的变量。当前进程中有效,其他进程及当前进程的子进程无效。定义在脚本或者当前终端中,脚本执行完毕或当前终端结束(窗口关闭)变量失效。

本地变量特点:

  • 作用域:只作用于当前shell

  • 生命周期:当前shell结束,本地变量失效

  • 应用场景:临时变量

环境变量

定义在用户家目录下的.bashrc.bash_profile文件中,用户私有变量,只能本用户使用。当前进程有效,并且能够被子进程调用。

  • 查看当前用户的环境变量:env命令
  • 查询当前用户的所有变量(临时变量与环境变量):set命令
  • 将当前变量变成环境变量:export命令(,)

环境变量特点:

  • 作用域:父shell及其子shell

  • 生命周期:注销用户或者关机

  • 应用场景:用户私有变量

  • 永久定义(将一个本地变量变成环境变量):~/.bash_profile~/.bashrc文件(用户登录成功后这两个文件被加载)

将临时变量变成环境变量:
	创建临时变量:
		# age=100
			[admin@server ~]$ age=100
			[admin@server ~]$ echo $age
				100
			[admin@server ~]$ env | egrep 'age=100'		=>	环境变量中不存在此age变量
			[admin@server ~]$ set | egrep 'age=100'		=>	age变量存在临时变量中
				age=100

	加入环境变量:
		# export age		
			[admin@server ~]$ export age		=>	临时将一个本地变量(临时变量)加入环境变量	
			[admin@server ~]$ env | egrep 'age=100'		=>	加入成功,环境变量中可以找到age变量
				age=100

定义一个永久生效的本地变量:只能本用户使用
	基于.bash_profile 文件定义:
		# vim ~/.bash_profile		=>	定义
			age=100
		# source ~/.bash_profile	=>	引用文件
	基于.bashrc	文件定义
		#vim ~/.bashrc			=>	定义
			age=100		
		# source ~/.bashrc		=>	引用文件

export 命令说明:

  • export 命令只是临时将本地变量变成环境变量,当前父shell结束则收回变量
  • export命令的作用域是当前shell及其子shell

需要注意

  • export命令变量输出(临时变量变成环境变量)是在当前shell中创建的,所以这个环境变量是在当前shell的环境变量里,不作用与当前shell同级的shell中。如:终端1变量输出一个临时变量,终端2不能调用

那为系统中的环境变量可以在各个终端下使用?

  • 这是因为~/.bash_profile~/.bashrc文件在用户登录时被加载了,它的作用域是当前用户父shell的其他所有子shell
export命令说明:
	用户登录时:
		用户登录到Linux系统后,系统将启动一个用户shell。在这个shell中,可以使用shell命令、声明变量、
		创建并运行shell脚本程序

	运行脚本时:
		运行shell脚本程序时,系统将创建一个子shell。此时,系统中将有两个shell,一个是登录时
		系统启动的shell,另一个是系统为运行脚本程序创建的shell。当一个脚本程序运行完毕,
		它的脚本shell将终止,可以返回到执行该脚本之前的shell

从这种意义来说,用户可以有许多shell,每个shell都是由某个shell(称为父shell)派生的。
在子shell中定义的变量只能在该子shell内有效。如果在一个shell脚本程序中定义了一个变量,
当该脚本程序运行时,这个定义的变量只是该脚本程序的一个局部变量,其他的shell不能引用它,
要使某个shell的值可以在其他shell中被改变,可以使用export命令对已定义的变量进行输出

export命令将使系统在创建每一个新的shell时定义这个变量的拷贝。这个过程称之为变量输出

父shell与子shell:

在这里插入图片描述

当前父shell中定义变量分为局部变量和全局变量,不同点是局部变量只能作用于本父shell,子shell无法继续使用,如果使用export命令将局部变量定义为全局变量,那么父shell在创建子shell的时候会将该变量一同复制给子shell环境

export命令变量输出说明:

1.sh脚本中定义一个变量输出,在2.sh脚本中验证是否成功:
	# vim 1.sh
		#!/bin/bash
		export _name='xjj'		=>	父shell定义一个全局变量
		_Pi='yuan'				=>	定义一个本地变量
		sleep 3				=>	等待3秒
		sh 2.sh				=>	执行2.sh

	# vim 2.sh
		#!/bin/bash
		echo "name:$_name"		=>	输出当前shell的_name变量
		echo "_Pi:$_Pi"		=>	输出当前shell的_Pi变量

	#l ./1.sh		=>	等待三秒输出成功,说明先执行1.sh的父shell再执行2.sh的子shell	
	[root@server ~]# ./1.sh
		_name:xjj		=>	_name变量调用成功,说明export变量输出成功
		_Pi:			=>	_Pi变量无法调用成功,因为是局部变量

全局变量

可以使用export命令将本地变量输出为当前shell中的全局变量(注意:只在当前父shell及其子shell有效)

  • 查看全局变量:printenv命令

全局变量特点:

  • 作用域:所有用户

  • 生命周期:关机

  • 应用场景:公共变量

  • 永久定义:/etc/profile/etc/bashrc文件(用户登录前这两个文件就已经加载成功了)

备注:当全局变量和环境变量定义了同一个变量时以环境变量的定义为准。因为环境变量的文件后加载,所以会覆盖掉全局变量的文件中的变量

全局变量文件说明:

局部文件:作用于每个用户
	$HOME/.bash_profile  	=>	当前用户的环境变量
	$HOME/.bashrc     		=>	当前用户的bash信息(aliase、umask等)
	
全局文件:作用于全部用户
	/etc/profile   		   =>	系统和每个用户的环境变量信息
	/etc/bashrc            =>	使用bash shell用户全局变量

	$HOME/.bash_logout  	=>	每个用户退出当前shell时最后读取的文件


用户登录系统读取相关文件的顺序:
#l	/etc/profile——>		/etc/bashrc——>		$HOME/.bash_profile——>		$HOME/.bashrc——>	$HOME/.bash_logout
	 全局环境变量		全局base shell信息	    用户环境变量				用户base shell信息	用户退出时读取这个文件

如果想让修改过后的局部或全局文件生效需要重新加载:用source命令读取一下
	# source /etc/bashrc		=>	让系统重新加载这个文件的配置,就会覆盖原来的

内置变量

系统变量(内置base变量):shell本身已经固定好了它的名字和作用

内置变量特点:

  • 作用域:所有用户
  • 生命周期:关机
  • 应用场景:公共变量
内置变量说明:
	#l	$?	:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常 或出错
		返回状态值:
			0:表示命令执行成功
			127:表示command not found
			126:表示找到了该命令但无法执行(权限不够)
			12:表示没有那个文件或目录

	#l	$$	:当前所在进程的进程号
	#l	$!	:后台运行的最后一个进程号
	#l	!$	:调用最后一条命令历史中的参数
	#l	!!	:调用最后一条历史命令

	#l	$#	:脚本后面接的参数个数
	#l	$*	:脚本后面所有参数,参数当成一个整体输出,每个变量参数之间以空格隔开
	#l	$@	:脚本后面所有参数,参数是独立的,也是全部输出
				=>	$*和$$的区别是一个是整体输出,一个是独立输出,可以用for i in $*(@)do echo $i;done,对脚本传参查看输出的值

	#l	$0	:当前执行的进程/程序名
	#l	$1~$9	:位置参数变量,应用于脚本外传参时,从外部传入参数到脚本内部执行
	#l	${10}~${n}	:扩展位置参数变量,第10个位置变量必须用{}大括号括起来



演示:
	#l	$? 变量返回上一条命令执行状态
		[root@server ~]# ls
			1  1.sh  2.sh
		[root@server ~]# echo $?
			0
		[root@server ~]# lsls
			bash: lsls: command not found...
		[root@server ~]# echo $?
			127

	#l	$$、$#、$*、$@ 变量的使用
		[root@server ~]# vim demo.sh
			#!/bin/bash
			echo "\\$$=$$"
			echo "\\$0=$0"
			echo "\\$#=$#"
			echo "\\$*=$*"
			echo "\\$1=$1"
			echo "\\$2=$2"
			echo "\\$3=$3"
			echo "\\$4=$4"
			echo "\\$5=$5"	
		[root@server ~]# sh demo.sh a b c d e		=>	给五个参数,脚本外传参,给脚本内部执行
			$$=39612			=>	返回当前脚本所在进程PID
			$0=demo.sh			=>	返回返回当前脚本进程的程序名
			$#=5			=>	返回参数个数
			$*=a b c d e	=>	返回执行了哪些参数
			$@=a b c d e	=>	返回执行了哪些参数
			$1=a		=>	返回第1个参数
			$2=b		=>	返回第2个参数				
			$3=c		=>	返回第3个参数
			$4=d		=>	返回第4个参数
			$5=e		=>	返回第5个参数

扩展:其他变量

当定义一个变量的内容是文件的时候,可以通过dirname和basename命令去查看

扩展变量说明:

扩展说明:
	取出有个目录下的目录和文件:dirname和basename

	变量内容的输出和替换:
		%:代表从右往左去掉一个/key/
		%%:代表从右往左去掉最大的/key/,即保留最后一个以啥分隔左边内容
		#:代表从左往右去掉一个/key/
		##:代表从左往右去掉最大的/key/,即保留最后一个以啥分隔右边内容
		*:匹配分隔符,后接分隔符号


演示:
	#l 变量=文件路径:
		[root@server ~]# A=/tem/base/shell/demo.sh		=>	定义变量值
		[root@server ~]# echo $A		=>	正常读取
			/tem/base/shell/demo.sh
		[root@server ~]# dirname $A		=>	取出目录,通过"dirname"命令
			/tem/base/shell
		[root@server ~]# basename $A	=>	取出文件,通过"basename"命令
			demo.sh

	#l  获取变量,*代表匹配 、.代表分隔符
		[root@server ~]# url=www.nbplus.com
		[root@server ~]# echo $url
			www.nbplus.com
		[root@server ~]# echo ${#url}		=>	"#" 获取变量长度
			14
		[root@server ~]# echo ${url#*.}		=>	"#*.".为分隔符,从左往右去掉一个字段
			nbplus.com
		[root@server ~]# echo ${url#*n}		=>	"#*n" 以n为分隔符,从左往右去掉一个字段
			bplus.com
		[root@server ~]# echo ${url##*.}	=>	"##*.".为分隔符,从左往右去掉两
			com		
		[root@server ~]# echo ${url%.*}		=>	"%.*".为分隔符,从右往左去掉一个字段
			www.nbplus
		[root@server ~]# echo ${url%%.*}	=>	"%%.*".为分隔符,从右往左去掉两个字段
			www

变量取值

读取变量内容符:$

读取方法:$变量名

以上是关于shell编程之变量定义的主要内容,如果未能解决你的问题,请参考以下文章

shell编程之变量定义

shell编程之常用系统变量自定义变量特殊变量运算符

Shell编程之通配符和用户自定义变量

shell编程之变量

linux之shell编程

shell编程