Shell 变量及运用

Shell 变量 

变量是 Shell  传递数据的一种方法。变量是用来代表每个值的符号名。我们可以把变量当成一个容器,通过变量,可以在内存中存储数据。也可以在脚本执行中进行修改和访问存储的数据。 

1.   变量的设置规则: 

(1)   变量名称通常是大写字母,它可以由数字、字母(大小写)和下划线_组成。变量名区分大小写;但是大家要注意变量名称不能以数字开头。 

(2)   等号  =  用于为变量分配值,在使用过程中等号两边不能有空格。 

(3)   变量存储的数据类型是整数值和字符串值。 

(4)   在对变量赋于字符串值时,建议大家用引号将其括起来。因为如果字符串中存在空格隔符号。需要使用单引号或双引号。 

(5)   要对变量进行调用,可以在变量名称前加美元符号$号。 

(6)   如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含“$变量名”或用${变量名}包含。 

2.   变量的分类 

按照变量的作用可以分成 4 类: 

(1)   用户自定义变量。 

(2)   环境变量:这种变量中主要保存的是和系统操作环境相关的数据。   

(3)   位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。   

(4)   预定义变量:是 Bash 中已经定义好的变量,变量名不能自定义,变量作用也是固定的。    

按照变量作用域可以分成 2 类:全局变量和局部变量。 

(1)   局部变量是 shell  程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量和预定义变量。 

(2)   全局变量是环境变量,其值不随 shell  脚本的执行结束而消失。 

用户定义变量 

变量名命名规则:由字母或下划线打头,不允许数字开头,后面由字母、数字或下划线组成,并且大小写字母意义不同。在使用变量时,在变量名前加$号。

例 19.1给变量 VAR1 赋值。 

[root@xuegod63 ~]# VAR1=123      #赋值变量,变量名为 VAR1,值为 123。 

[root@xuegod63 ~]# echo $VAR1    #使用 echo $变量名称即可打印变量的值。 

123 

 

例 19.2:错误的赋值方式,不允许数字开头,等号两边不能有空格。 

[root@xuegod63 ~]# VAR2 =456        #等号的右边有空格。 

bash: VAR2:  未找到命令... 

[root@xuegod63 ~]# VAR2= 456        #等号的左边有空格。 

bash: 456:  未找到命令... 

[root@xuegod63 ~]# VAR2 = 456      #等号的两边有空格。 

bash: VAR2:  未找到命令... 

[root@xuegod63 ~]# 3VAR2 = 456      #变量名为数字开头,等号的右边有空格。 

bash: 3VAR2:  未找到命令... 

 

例 19.3:变量值的叠加,使用${}。 

$name 是${name}的简化版本,但是在某些情况下,还必须使用花括号引起的方式来消除歧义并避免意外的结果。 

[root@xuegod63 ~]# VAR4=mysql     #赋值变量。 

[root@xuegod63 ~]# echo $VAR4      #打印变量。 

mysql 

[root@xuegod63 ~]# echo $VAR4-db.log    #打印变量并在变量后跟上其他内容。 

mysql-db.log 

[root@xuegod63 ~]# echo $VAR4.db.log 

mysql.db.log 

[root@xuegod63 ~]# echo $VAR4db.log      #在变量不后跟上的内容中没有分隔号时,默认会把返段内容中的点号为分隔,把 VAR4db 当作变量了,实际上并没有此变量存在,因此结果为.log。 

.log 

[root@xuegod63 ~]# echo ${VAR4}db.log    #在变量不后跟的内容并非有分隔号时,使用{}括起变量名即可。 

mysqldb.log 

命令的替换,使用$()或反引号。 

例 19.4:在命令就调用 date 命令。 

扩展:date 命令是显示或设置系统时间不日期。 

-s<字符串>:根据字符串来设置日期不时间。字符串前后必须加上双引号。 

<+时间日期格式>:指定显示时,使用特定的日期时间格式。 

 

例 19.5:格式化输出: 

[root@xuegod63 ~]# date +"%Y-%m-%d"     #打印日期,一般备份数据需要用到。 

2018-05-25 

[root@xuegod63 ~]# date +"%Y-%m"        #叧显示年月。 

2018-05 

[root@xuegod63 ~]# date +"%Y-%m-%d %H:%M.%S"        #日期加时间。 

2018-05-25 17:51.36 

[root@xuegod63 ~]# date +"%Y/%m/%d %H/%M/%S"      #使用/做分隔符。 

2018-05-25 17-51-43 

[root@xuegod63 ~]# date +"%Y-%m-%d-%H-%M-%S"    #使用-做分隔符,一般备份数据需

要。用返个。 

注:  %y  年份叧显示 2 位,    %Y 年份显示 4 位。 

 

date 命令加减操作: 

# date +%Y%m%d                                       #显示当天年月日。 

# date -d "+1 day" +%Y%m%d                  #显示明天的日期。 

# date -d "-1 day" +%Y%m%d                    #显示昨天的日期。 

# date -d "-1 month" +%Y%m%d              #显示上一月的日期。 

# date -d "+1 month" +%Y%m%d            #显示下一月的日期。 

# date -d "-1 year" +%Y%m%d                  #显示前一年的日期。 

# date -d "+1 year" +%Y%m%d                #显示下一年的日期。 

 

设定时间: 

# date -s 20180523                              #设置成 20120523,返样会把具体时间设置成空 00:00:00。 

# date -s 01:01:01                                  #设置具体时间,不会对日期做更改。 

# date -s "2018-05-23 01:01:01"     #返样可以设置全部时间。 

 

例 19.6:  在命令中调用 date 命令输出值 

[root@xuegod63 ~]# echo `date`    #反引号作用,把引起的命令执行的结果交给前一个命令。 

2018 年  05 月  25 日  星期五  17:41:29 CST 

[root@xuegod63 ~]# echo $(date)             #$()不把引号功能相同。 

2018 年  05 月  25 日  星期五  17:41:42 CST 

[root@xuegod63 ~]# echo `date +"%Y-%m-%d"` 

2012-05-23  

命令的嵌套使用,使用$( $( )) 

双重$($()),先执行括号中的$()的命令,把结果交给外边的$()中的命令处理。   

[root@xuegod63 ~]# find /root/ -name *.txt 

[root@xuegod63 ~]# VAR6=$(tar zcvf root.tar.gz $(find /root/ -name *.txt)) 

tar:  从成员名中删除开头的“/” 

 

[root@xuegod63 ~]# echo $VAR6      #查看值,VAR6 中存储着 tar 的标准输出。 

/root/.cache/tracker/db-version.txt /root/.cache/tracker/db-locale.txt 

/root/.cache/tracker/parser-sha1.txt /root/.cache/tracker/locale-for-miner-user-guides.txt 

/root/.cache/tracker/locale-for-miner-apps.txt /root/.cache/tracker/last-crawl.txt 

。。。 

实战:分享一个系统时间错误,引起 tar 报警告。 

[root@xuegod63 ~]# date -s "2018-03-03 21:25:00" 

[root@xuegod63 ~]# tar zxvf root.tar.gz -C /opt/ 

root/.cache/tracker/db-version.txt 

tar: root/.cache/tracker/db-version.txt:时间戳  2018-09-19 13:05:18  是未来的168094624.438537189  秒之后。 

注: 如果弹出返个消息,是因为咱们的当前系统的时间不对。  比如:当前系统的时间晚于文件的mtime 时间。 

[root@xuegod63 ~]# ls /opt/root/.mozilla/firefox/wggimqlt.default/ -a    #解压成功。

Shell 中单引号和双引号区别 

‘’  在单引号中所有的字符包括特殊字符($,'',``和\)都将解释成字符本身而成为普通字符。 

“”  在双引号中,除了$, '', ``和\以外所有的字符都解释成字符本身,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义。 

 

注:\转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如\$将输出“$”符号,而不当做是变量引用。 

例: 

[root@xuegod63 ~]# echo $VAR1 

123 

[root@xuegod63 ~]# echo \$VAR1 

$VAR1 

 

例 19.7:给变量值赋于多个单词,需要使用单引号和双引号。 

[root@xuegod63 ~]# VAR8='xuegdo mk' 

[root@xuegod63 ~]# echo $VAR8 

xuegdo mk 

 

例 19.8:赋值时单引号和双引号的区别。 

[root@xuegod63 ~]# VAR8='xuegod mk $VAR1' 

[root@xuegod63 ~]# VAR9="xuegod mk $VAR1"        #双引中$符号有作用。 

[root@xuegod63 ~]# echo $VAR8 

xuegod mk $VAR1 

[root@xuegod63 ~]# echo $VAR9 

xuegod mk 123 

注:单引号之间的内容原封不动赋值给变量,双引号之间的内容如有特殊符号会保留它的特殊含义。 

删除变量 

[root@xuegod63 ~]# unset VAR1    #使用 unset  变量名称即可删除变量。 

[root@xuegod63 ~]# echo $VAR1 

环境变量 

1.在 Bash Shell 中,环境变量分为两类:全局变量和局部变量。

2.全局变量:对于 Shell 会话和所有的子 shell 都是可见的。 

3.局部变量:它叧在自己的迕程当中使用。 

 

例 19.8:局部变量。 

[root@xuegod63 ~]# VAR1=123 

[root@xuegod63 ~]# echo $VAR1 

123 

[root@xuegod63 ~]# vim a.sh 

#!/bin/bash 
echo $VAR1

[root@xuegod63 ~]# echo $VAR1 

123 

[root@xuegod63 ~]# bash a.sh                #执行 a.sh  时,会使用另一个 bash 去执行,就访问不到$VAR1 的值。 

 

例 19.9:env 命令查看所全局变量 

[root@xuegod63 ~]# env   

[root@xuegod63 ~]# env | grep PATH 

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin 

 

例 19.10:使用 export 把这个局部变量输出为全局变量。 

[root@xuegod63 ~]# export VAR1=xuegod 

[root@xuegod63 ~]# echo $VAR1 

xuegod 

[root@xuegod63 ~]# vim a.sh            #写入以下内容。 

#!/bin/bash 
echo $VAR1

[root@xuegod63 ~]# bash a.sh         #引用全局变量成功。 

xuegod 

 

问:  虽然我们设置了 export 全局变量,但是新开的 Xshell 连接中,还是读不到变量 VAR1,怎么办?

如图  19-3  所示。 

image.png

例 19.11:让变量永久生效,可以把定义好的变量写入配置文件。 

当登录系统或新开启一个 ssh 连接启动 bash 迕程时,一定会加载返 4 个配置文件: 

[root@xuegod63 ~]# vim /etc/profile            #系统全局环境和登录系统的一些配置。 

[root@xuegod63 ~]# vim /etc/bashrc            #shell 全局自义配置文件,用于自定义 shell。 

[root@xuegod63 ~]# vim /root/.bashrc          #用于单独自定义某个用户的 bash。 

[root@xuegod63 ~]# vim /root/.bash_profile    #用户单独自定义某个用户的系统环境。 

 

问:如何知道新建一个 ssh 连接,加载返 4 个配置文件先后顺序?   

答:可以每个文件的最后,追加一个 echo 命令,输出一下文件的名字。 

[root@xuegod63 ~]# echo 'echo    /etc/profile ' >> /etc/profile 

[root@xuegod63 ~]# echo 'echo    /etc/bashrc' >> /etc/bashrc 

[root@xuegod63 ~]# echo 'echo    /root/.bashrc ' >> /root/.bashrc 

[root@xuegod63 ~]# echo 'echo    /root/.bash_profile ' >> /root/.bash_profile 

[root@xuegod63 ~]# ssh [email protected]          #弹出以下信息,就知道有优先级了。 

/etc/profile 

/etc/bashrc   

/root/.bashrc 

/root/.bash_profile 

 

问:知道加载的顺序有什么用? 

可以在返里添加木马程序,叧要管理登录系统,就触发木马程序!现在大家知道学习操作系统原理的作用了吧。 

[root@xuegod63 ~]# echo 'touch    /tmp/profile.txt ' >> /etc/profile     

[root@xuegod63 ~]# echo 'touch    /tmp/bash_profile.txt ' >> /root/.bash_profile 

 

下面开始插入永久变量: 

[root@xuegod63 ~]# vim /etc/profile          #在文件的最后插入。 

export VAR9=xuegod                    #=等号两边不能有空格。 

[root@xuegod63 ~]# source /etc/profile        #重新加载 profile 文件。 

新打开的链接中,也有了,如图  19-4  所示。 

image.png

设置PATH环境变量

SHELL要执行某一个程序,它要在系统中去搜索这个程序的路径,path变量是用来定义命令和查找命令的目录,当我们安装了第三方程序后,可以把第三方程序bin目录添加到这个path路径内,就可以在全局调用这个第三方程序的

例1:

[root@xuegod63 ~]# vim /opt/backup                  

#!/bin/bash
echo "Backup data is OK!"

[root@xuegod63 ~]# chmod +x /opt/backup  

[root@xuegod63 ~]# /opt/backup

[root@xuegod63 ~]# backup

bash: backup: 未找到命令...

 

将backup命令添加PATH中

[root@xuegod63 ~]# PATH=/opt/:$PATH

[root@xuegod63 ~]# backup   #发现命令可以直接执行了,不用写全路径了

[root@xuegod63 ~]# vim /etc/profile  # 在文件最后追加以下内容,永久生效

export PATH=/opt/:$PATH

[root@xuegod63 ~]# source  /etc/profile   #重新加载配置文件,使用配置生效

shell位置变量

Shell解释执行用户的命令时,将命令行的第一个字符作为命令名,而其它字符作为参数。  

$0  获取当前执行shell脚本的文件文件名,包括脚本路径,命令本身

$n  获取当前脚本的第n个参数 n=1,2.....n 当n大于9时 用${10}表示。

例子:

[root@xuegod63 ~]# vim print.sh  

#!/bin/bash
echo "本shell脚本的文件名: $0"
echo "第1个参数:  $1"
echo "第2个参数:  $2"
echo "第3个参数:  $3"
echo "第4个参数:  $4"

[root@xuegod63 ~]# chmod +x print.sh

[root@xuegod63 ~]# ./print.sh 111  222 a.txt  444

本shell脚本的文件名: ./print.sh

第1个参数:  111

第2个参数:  222

第3个参数:  a.txt

第4个参数:  444

使用场景:服务器启动传参数

[root@xuegod63 ~]# /etc/init.d/network restart

特殊变量

有些变量是一开始执行Script脚本时就会设定,且不能被修改,但我们不叫它只读的系统变量,而叫它特殊变量。这些变量当一执行程序时就有了,以下是一些特殊变量:

$*

以一个单字符串显示所有向脚本传递的参数;

如"$*"用【"】括起来的情况、以"$1 $2 … $n"的形式输出所有参数

$#

传递到脚本的参数个数

$$

当前进程的进程号PID

$?

显示最后命令的退出状态;0表示没有错误,其他任何值表明有错误

$!

后台运行的最后一个进程的进程号pid

例子:

[root@xuegod63 ~]# vim special_variable.sh  #写入以一下内容

#!/bin/bash
echo "$* 表示这个程序的所有参数 "
echo "$#  表示这个程序的参数个数"
echo "$$  表示程序的进程ID "
touch /tmp/b.txt &
echo "$!  执行上一个后台指令的PID"
echo "$$  表示程序的进程ID "
echo "$? 表示上一个程序执行返回结果 "

[root@xuegod63 ~]# bash special_variable.sh  11 22 33 44 55

11 22 33 44 55 表示这个程序的所有参数

11 22 33 44 55 表示这个程序的所有参数

5  表示这个程序的参数个数

45502  表程序的进程ID

45504  执行上一个后台指令的PID

45502  表程序的进程ID

0 表示上一个程序执行返回结果

 

例2:常用的环境变量

[root@xuegod63 opt]# cd /opt/

[root@xuegod63 opt]# vim env.sh

#!/bin/bash
echo $HOME
echo $PATH
echo $PWD

[root@xuegod63 opt]# bash env.sh

/root

/opt/:/opt/:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin

/opt

版权声明:
作者:WaterBear
链接:https://l-t.top/1585.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>