这篇文章主要讲解 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编程实战》这本书时的笔记,如有任何版权问题,请联系留言。