首页 > 代码库 > 《跟老男孩学Linux运维之shell编程实战》-第二章 shell变量的核心基础

《跟老男孩学Linux运维之shell编程实战》-第二章 shell变量的核心基础

这篇文章主要讲解 shell变量的核心基础。

1.变量是什么?

变量是什么?可能有好多人不明白,简单地说,变量就是用一个固定的字符串(也可能是字符、数字等的组合)代替更多、更复杂的内容,该内容里可能还会包含变量、路径、字符串等其他的内容。

    变量的赋值方式为:先写变量名称,紧接着是“=”这个字符,最后是值,中间无任何空格(变量的内容一般要加双引号,以防止出错,特别是当值里的内容之间有空格时)。

    如何打印变量?通过echo命令加上$变量名 打印变量的值:

例如:定义变量和打印变量:

[root@www ~]# XiaoYu="My name is XiaoYu"  ==>定义变量,变量名为XiaoYu,变量的内容为:"My name is XiaoYu"

[root@www ~]# echo $XiaoYu                        ==>打印变量XiaoYu的值
My name is XiaoYu

2.变量的类型:

变量可分为两类:环境变量(全局变量)和普通变量(局部变量)

(1)   环境变量也可称为全局变量,可以在创建它们的shell及其派生出来的任意进程shell中使用,环境变量又可以分为自定义环境变量和bash内置的环境变量。

  •  环境变量一般是指用export内置命令导出的变量,用于定义shell的运行环境,保证shell命令的正确执行。shell通过环境变量来确定登录用户名、命令路径、终端类型、登录目录等,所有的环境变量都是系统全局变量,可以用于所有子进程中。

  • 环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,如果希望变量永久生效,可在用户家目录下的.bash_profile或.bashrc或全局配置文件/etc/bashrc或/etc/profile文件中定义。

  • 按照系统规范,所有环境变量的名字均采用大写形式。在将环境变量应用于用户进程程序之前,都应该用export命令导出定义,例如:export XIAOYU=1。

  • 查询系统中的环境变量:set(输出所有的变量,包括全局变量和局部变量)、env(只显示全局变量) 、declare(显示所有的变量、函数、整数和已经导出的变量)。

(2)  普通变量也可称为局部变量,只能在创建它们的shell函数或shell脚本中使用。

3.自定义环境变量:

设置环境变量,就要在给变量赋值之后或者在设置变量时使用export命令,其实出了export命令,带-x选项的declare内置命令也可以完成同样的功能。export命令和declare命令的格式如下:

(1)export  变量名=value

(2)变量名=value;export 变量名

(3)declare -x 变量名=value

以下为定义变量并赋值的方法:

[root@www ~]# export NAME=XiaoYu
[root@www ~]# declare -x NAME=XiaoYu
[root@www ~]# NAME=XiaoYu;export NAME

以下为自定义全局环境变量的示例:

[root@www ~]# cat /etc/profile | grep XiaoYu
export NAME=‘XiaoYu‘          ==>编辑文件/etc/profile,add此行,保存退出

[root@www ~]# source /etc/profile      ==>或 . /etc/profile 使/etc/profile生效

[root@www ~]# echo $NAME               ==>打印变量
XiaoYu

[root@www ~]# env | grep XiaoYu        ==>查看定义的结果
NAME=XiaoYu

4.环境变量永久生效的配置文件:

(1)用户的环境变量配置:

[root@www ~]# ls /root/.bashrc    ==>推荐在此文件中优先配置
/root/.bashrc
[root@www ~]# ls /root/.bash_profile
/root/.bash_profile

提示:对于用户的环境变量设置,比较常见的是用户家目录下的.bashrc.bash_profile

(2)全局环境的配置文件:

/etc/profile

/etc/bashrc

/etc/profile.d/

若要在登录后初始化或显示加载内容,则把脚本文件放在/etc/profile.d/目录下即可(无需加执行权限)

5.设置登录提示的两种方法:

方法一:在/etc/motd里增加提示的字符串:

[root@www ~]# cat /etc/motd
welcome to ......

方法二:在/etc/profile.d下面增加如下脚本:

[root@www ~]# cat /etc/profile.d/welcome.sh  ==>脚本内容根据实际情况书写

6.显示与取消环境变量:

(1)通过echo或printf命令打印变量:

[root@www ~]# echo $NAME
XiaoYu
[root@www ~]# printf "$NAME\n"  ==>printf是一个更复杂的格式化打印内容的工具,一般不需要
XiaoYu

(2)用env或set显示默认的环境变量

(3)unset取消本地变量和环境变量:

[root@www ~]# echo $NAME
XiaoYu
[root@www ~]# unset NAME
[root@www ~]# echo $NAME
                                                     ==>返回结果为空

环境变量知识小结:

  • 变量名通常要大写。

  • 变量可以在自身的shell及子shell中使用。

  • 常用export来定义环境变量。

  • 执行env默认可以显示所有的环境变量名称及对应的值

  • 输出时用“$变量名”,取消时用“unset  变量名”

  • 书写crond定时任务时要注意,脚本要用到的环境变量最好先在所执行的shell脚本中重新定义。

  • 如果希望环境变量永久生效,则可以将其放在用户环境变量文件或全局环境变量文件里。

7.普通变量:

(1)定义本地变量:本地变量在用户当前shell生存期的脚本中使用。

普通变量的定义:

变量名=value                ==>赋值时不加引号

变量名=‘value’         ==>赋值时加单引号

变量名=“value”         ==>赋值时加双引号

变量的内容可以用单引号或双引号引起来,也可以加引号,但是这三者的含义是不同的。

将连续的普通字符串的内容赋值给变量,不管用不用引号,或者不管用什么引号,它的内容是什么,打印变量时就会输出什么。

例:定义变量a、b、c,并打印出各个变量的值。

[root@www ~]# a=192.168.1.2
[root@www ~]# b=‘192.168.1.2‘
[root@www ~]# c="192.168.1.2"
[root@www ~]# echo a=$a
a=192.168.1.2
[root@www ~]# echo b=$b
b=192.168.1.2
[root@www ~]# echo c=$c
c=192.168.1.2
[root@www ~]# echo c=${c}
c=192.168.1.2

提示:$变量名表示输出变量,可以用$c和${c}两种用法

接着上述变量的得结果,继续输入如下内容:

[root@www ~]# a=192.168.1.2-$a
[root@www ~]# b=‘192.168.1.2-$a‘

[root@www ~]# c="192.168.1.2-$a"
[root@www ~]# echo $a
192.168.1.2-192.168.1.2
[root@www ~]# echo $b
192.168.1.2-$a
[root@www ~]# echo $c
192.168.1.2-192.168.1.2-192.168.1.2

上述案例说明,当内容为简单连续的数字、字符串、路径名时,定义变量在不加引号的情况下,值里有变量的会被解析后再输出;

定义变量时,如果使用了单引号,则变量的内容是什么,就输出什么,即所见即所得。定义变量时使用了双引号,输出变量内容时引号里的变量及命令会经过解析后再输出内容。

提示:数字内容的变量定义可以不加引号,其他没有特别要求的字符串等定义时最好都加上双引号,如果需要原样输出就加单引号,定义变量加双引号是最常见的使用场景。

(2)在shell中定义变量名及变量内容赋值的要求:   

    变量名一般由字母、数字、下划线组成,可以以字母或下划线开头。

(3)把一个命令的结果作为变量的内容赋值的方法:

方法一:变量名=` ls`

方法二:变量名=`$(ls)`

局部(普通)变量定义及赋值的经验小结:

定义变量:

  • 若变量的内容为连续的数字或字符串,赋值时,变量内容两边可以不加引号。

  • 变量的内容很多时,如果有空格且希望解析内容中的变量,就加双引号。

  • 希望原样输出变量中的内容时就用单引号。

  • 希望变量的内容时命令的解析结果就用反撇号或者用$( )括起来。

输出变量:

  •  使用“$变量名”即可输出变量的内容,常用“echo $变量名”的方式,当然也可用printf代替echo输出更复杂的格式内容。

  • 在变量名前加$可以取得该变量的值,$a和${a}的写法不同,但是效果相同。

  • 用echo等命令输出变量的时候,也可用单引号、双引号、不加引号,如echo$a 、echo “$a”、echo ‘$a’,用法和前面变量内容定义的总结是一致的。

  • $dbname_tname,当变量后面连接有其他的字符串的时候,必须给变量加上大括号{ },例如:$dbname_tname就用改为${dbname}_tname

8.在定义变量、赋值及变量输出加单引号、双引号、反撇号和不加引号的简要说明。

   名称
                                                                             解释
单引号
所见即所得,即输出时会将单引号内的所有内容都原样输出,或者描述为单引号里面看到的是什么,就会输出什么。
双引号
输出双引号内的所有内容,如果内容中有命令(要用反撇号引起来)、变量、特殊转义符等,会先把变量、命令、转义符解析出结果,然后再输出最终内容,推荐使用。
无引号
赋值时,如果变量内容中有空格,则会造成赋值不完整。而输出内容时,会将含有空格的字符串视为一个整体输出;如果内容中有命令(要用反撇号引起来)、变量等,则会先把变量、命令解析出结果,然后输出最终内容;如果字符串中带有空格等特殊字符,则有可能无法完整地输出,因此需要改加双引号。一般连续的字符串、数字、路径等可以不加任何引号进行赋值和输出,不过最好是用双引号代替无引号的情况,特别是对变量赋值时。
反引号
` `一般用于引用命令,执行的时候命令会被执行,相当于$( ),赋值和输出都要用` `将命令引起来。

提示:上述结论同样适用于grep、awk。

这里仅为Linux shell下的结论,对于awk语言会有点特别。

AWK调用shell变量结论如下:

技术分享

建议:

  • 在脚本中定义普通字符串变量时,应尽量把变量的内容用双引号引起来。

  • 单纯的数字的变量内容可以不加引号。

  • 希望变量的内容原样输出时需要加单引号。

  • 希望变量值引用命令并获取命令的结果时就用反引号(反撇号)或$( )。

8.关于自定义普通字符串变量的建议:

  • 内容是纯数字、简单的连续字符(内容中不带任何空格)时,定义时可以不加任何引号。

  • 没有特殊情况时,字符串一律都用双引号定义赋值,特别是多个字符串中间有空格时。

  • 当变量里的内容需要原样输出时,要用单引号。


结论:

(1)变量名及变量内容定义小结:

   a)变量名只能为字母、数字或下划线,只能以字母或下划线开头。    

   b)变量名的定义要有一定的规范,并且要见名知意。

   c)一般的变量定义、赋值常用双引号,简单连续的字符串可以不加引号;希望原样输出的用单引号。

   d)希望变量的内容是命令的解析结果时,要用反引号(反撇号),或者用$( )把命令括起来再赋值。

(2)shell定义变量时使用“=”的知识

 比较变量是否相等时可以用“=”或“==”。

(3)打印输出及使用变量的知识

    a)打印输出或使用变量时,变量名前要接$符号;变量名后面紧接其他字符的时候,要用大括号将变量部分单独括起来,在unset、export、(())等场景中使用但不打印变量时不加$。

    b)打印输出或使用变量时,一般加双引号或不加引号;如果是字符串变量,最好加双引号,希望原样输出时使用单引号。



以上为本人在读《跟老男孩学Linux运维之shell编程实战》这本书时的笔记,如有任何版权问题,请联系1476636160@qq.com。




本文出自 “shayatou_1990” 博客,请务必保留此出处http://shayatou1990.blog.51cto.com/12806916/1917018

《跟老男孩学Linux运维之shell编程实战》-第二章 shell变量的核心基础