二、Shell变量
什么是变量
变量是暂时存储数据的地方,所存储的数据存在于内存空间中,通过调用内存空间中变量的名字取出与变量对应的数据。
通俗一点就是变量是shell传递数据的一种方法,可以理解为存储数据的容器。
变量设置规则
1、 变量名是可以由数字、字母(大小写)和下划线_组成。区分大小写;但不能以数字开头。
2、 等号为变量赋值,等号两边不能有空格
3、 变量存储的数据类型是整数值和字符串值
4、 如果字符串中存在空格隔符号。需要使用单引号或双引号引起来
5、 要对变量进行调用,可以在变量名称前加美元符号$
6、 如果需要追加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含“$变量名”或用${变量名}包含(详看例)
例:变量值的叠加,使用${}
$name是${name}的简化版本,但是在某些情况下,还必须使用花括号引起的方式来消除歧义并避免意外的结果
[root@tzPC ~]# VAR4=mysql
[root@tzPC ~]# echo $VAR4
mysql
[root@tzPC ~]# echo $VAR4-db.log
mysql-db.log
[root@tzPC ~]# echo $VAR4db.log #发现输出的结果不是我们想要的,怎么办?
.log
[root@tzPC ~]# echo ${VAR4}db.log
mysqldb.log
变量的分类
1、用户自定义变量
2、环境变量:这种变量中主要保存的是和系统操作环境相关的数据。
3、位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。
4、预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。 如PATH
按照变量作用域可以分成2类:全局变量和局部变量。
局部变量是shell 程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量和预定义变量。
全局变量是环境变量,其值不随shell 脚本的执行结束而消失。
环境变量可分为自定义环境变量和bash内置环境变量。
环境变量及全局变量名字均采用大写。
局部变量在用户当前Shell生存期使用,如果当前Shell启动了另一个进程或退出,都将失效
env命令查看全局变量
[root@tzPC ~]# env |more
XDG_SESSION_ID=25
HOSTNAME=tzPC
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.149.1 56410 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root
...
printenv命令查看全局变量
[root@tzPC ~]# type -a printenv printenv is /usr/bin/printenv [root@tzPC ~]# printenv XDG_SESSION_ID=111 HOSTNAME=tzPC SELINUX_ROLE_REQUESTED= TERM=xterm SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=192.168.149.1 26026 22 SELINUX_USE_CURRENT_RANGE= SSH_TTY=/dev/pts/0 USER=root ...
输出全局变量的值
[root@tzPC ~]# echo $HOSTNAME tzPC
[root@tzPC ~]# printenv HOSTNAME
tzPC
[root@tz ~]# printf "$HOME\n" /root
使用export把局部变量改为全局变量
export VAR1="tz is good"
这种方式在新开的xshell窗口中是读不到变量的值,需要写入配置文件永久生效
使用set命令输出全局变量和局部变量
[root@tzPC ~]# set | more BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_ comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu") BASH_VERSION='4.2.46(2)-release' COLUMNS=104 DIRSTACK=() EUID=0 GROUPS=()
declare命令输出所有的变量、函数、导出的变量
[root@tzPC ~]# declare |more BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_ comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=() BASH_SOURCE=()
set -o 显示bash Shell所有参数的配置信息
[root@tz yum.repos.d]# set -o allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
自定义临时环境变量
命令行创建,退出Shell即丢失
三种方式自定义环境变量,如变量名NAME,值tz
[root@tz ~]# export NAME=tz [root@tz ~]# NAME=tz;export NAME [root@tz ~]# declare -x NAME=tz
设置PATH环境变量
[root@tzPC ~]# PATH=$PATH:/home/tz/Scripts
自定义永久环境变量
常见在用户加目录下配置文件中定义。
路径为
./bashrc(推荐在此配置)
.bash_profile
unset删除本地跟环境变量
[root@tz ~]# export NAME=tx [root@tz ~]# echo $NAME tx [root@tz ~]# unset NAME [root@tz ~]# echo $NAME
环境变量初始化
系统运行Shell方式有3种
- 通过系统用户登录后默认运行的Shell
- 非登录交互运行Shell
- 执行脚本运行非交互Shell
登陆shell查找环境变量的顺序为
- 加载/etc/profile主环境变量文件
- 执行/etc/profile.d下脚本文件
- 运行$HOME/.bash_profile用户环境变量文件
- 运行$HOME/.bashrc用户环境变量文件
- 运行/etc/bashrc全局环境变量文件
非登陆交互运行查找环境变量的顺序为
- 运行$HOME/.bashrc用户环境变量文件
- 运行/etc/bashrc全局环境变量文件
配置文件是依次执行的,里面都是脚本,如果被写入了木马程序就会被执行。
局部变量
局部变量的定义
变量名由字母、数字、下划线组成,可以以字母或下划线开头。
[root@tz ~]# name=tz
[root@tz ~]# name='tz'
[root@tz ~]# name="tz"
赋值
[root@tzPC Script]# value1=10 [root@tzPC Script]# value2=$value1 [root@tzPC Script]# echo $value2 10
局部变量的输出
不加引号输出
变量会被解析后再输出
输出内容为简单连续的数字、字符串、路径名时可以用
[root@tz ~]# echo my name is $name my name is tz
加单引号输出
原样输出
[root@tz ~]# echo 'my name is $name' my name is $name
或者加上转义符\
[root@tzPC Script]# echo "The cost of the item is \$15" The cost of the item is $15
加双引号输出
变量会被解析后再输出
[root@tz ~]# echo "my name is $name"
my name is tz
将命令结果作为变量值赋值
[root@tz ~]# lsdir=`ls` [root@tz ~]# echo $lsdir anaconda-ks.cfg VMwareTools-10.0.6-3595377.tar.gz [root@tz ~]# lsdir=$(ls) [root@tz ~]# echo $lsdir anaconda-ks.cfg VMwareTools-10.0.6-3595377.tar.gz
变量后面连接其他字符时需要加上大括号
[root@tz ~]# echo ${name}_pc tz_pc
案例:按当天日期打包网站站点目录做备份
[root@tz ~]# echo web_$(date +%F).tar.gz web_2020-04-05.tar.gz [root@tz ~]# tar zcf web_$(date +%F).tar.gz /web
将主机名作为压缩包名打包文件
[root@tz ~]# hostname=$(uname -n) [root@tz ~]# tar zcf $hostname.tar.gz /etc/
注意awk命令使用引号结果不一样,书P37,这里需要实际操作一下