Shell变量

变量命名

变量名的命名规则:

  • 变量名只能使用英文字母,数字和下划线,首字符不能以数字开头。
  • 不能使用bash里的关键字(可用help命令查看保留关键字)。
  • 变量名区分大小写

以下是无效变量命名示例:

?var=123

3var="str"

echo="str"

user*4=baby

变量定义

定义一个变量很简单:

变量名=值

示例:

name=myname

animal="Black Cat"

h=1

如果值是字符串建议使用双引号或单引号括起来

注意,变量名和等号之间不能有空格。

除了显式地直接赋值,还可以用语句给变量赋值,如:

for file in `ls /etc`  

或  

for file in $(ls /etc)  

以上语句将 /etc 下目录的文件名循环出来。

使用变量

使用一个定义过的变量,有两种方式:

$变量名 

或

${变量名}

示例:

mysite="devfz.cn"  

echo $mysite

echo http://${mysite}/list.html

注: 如果变量与其他字符连接时,必须使用第二种方式,即以{}区别分隔变量与普通字符,否则bash无法正确判断变量.

例如:

mysite="devfz.cn"
echo Hi,$mysitevery good

此时$mysitevery会认为是一个变量,但这个变量从未设置为所以会输出空

如果与变量相接的是/字符或中文,即不符合变量名的字符时,执行器仍是可以正确执行识别变量的,如:

dir1=bin

echo /usr/$dir1/config

mysite=程序员网址导航

echo 这个网站是$mysite网吗

执行结果会是:

/usr/bin/config
这个网站是程序员网址导航网吗

变量可以多次赋值,也可将变量值赋给其他变量. 示例:

mysite="dev.cn"
echo first name ${mysite}

oldname=$mysite
mysite="devfz.cn"

echo "old name" $oldname
echo "new name" $mysite

只读变量

只读变量即值不可改变的变量,有两个内置命令要定义只读变量:

  • readonly [变量名]|[-a 数组变量]
  • declare -r 变量名

下面的例子尝试更改只读变量:

#!/bin/bash  

myUrl="https://www.google.com"  

readonly myUrl  

myUrl="http://www.devfz.cn"  

运行脚本,结果如下:

/bin/sh: myUrl: This variable is read only.

删除变量

使用unset命令可以删除变量。语法:

unset 变量或函数名称

变量被删除后不能再次使用,unset命令不能删除只读变量。>unset也可删除环境变量

示例:

#!/bin/sh  

myUrl="http://devfz.cn"  

unset myUrl  

echo $myUrl  

上面示例执行将没有任何输出。

unset命令会先尝试取消变量,如果失败,再试着取消同名的函数。使用unset -v可指定取消变量 -f可指定取消函数

unset是删除变量, 而如果我们只是要将变量值清空但保留变量,可以直接将变量赋值为空,如下:

myname='devfz.cn'

myname=

变量类型

运行shell时,会同时存在三种变量:

1) 局部变量

局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

2) 环境变量

所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。export或declare -x 可设置环境变量,如:

declare -x HOME="/home/oper"
declare -x HOSTNAME="devfz.cn"

3) shell内置变量

shell内置变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

以下是部分bash的内置变量:

BASH_VERSION  bash的版本
CDPATH        cd命令搜索路径,自定义CDPATH可缩短键入路径长度
PATH          命令搜索路径
GROUPS        数组变量,包含用户所属组群列表
HOMENAME      主机名
LANG          目前系统语言系的名称
SHLVL         子shell层级数
$?            上一个命令执行结束后的传回值.0表示执行成功,非0表示执行有误
$$            目前bash shell的进程编号