03 Shell变量和引用

来源:互联网 发布:博途v14软件下载 编辑:程序博客网 时间:2024/06/04 18:46

3.1  深入认识变量
在程序设计语言中,变量是一个非常重要的概念。也是初学者在进行Shell程序设计之前必须掌握的一个非常基础的概念。只有理解变量的使用方法,才能设计出良好的程序。
3.1.1  什么是变量
顾名思义,变量就是程序设计语言中的一个可以变化的量,当然,可以变化的是变量的值。变量几乎所有的程序设计语言中都有定义,并且其涵义也大同小异。从本质上讲,变量就是在程序中保存用户数据的一块内存空间,而变量名就是这块内存空间的地址。
在程序的执行过程中,保存数据的内存空间的内容可能会不断地发生变化,但是,代表内存地址的变量名却保持不变。
3.1.2  变量的命名
在Shell中,变量名可以由字母、数字或者下划线组成,并且只能以字母或者下划线开头。对于变量名的长度,Shell并没有做出明确的规定。因此,用户可以使用任意长度的字符串来作为变量名。但是,为了提高程序的可读性,建议用户使用相对较短的字符串作为变量名。
在一个设计良好的程序中,变量的命名有着非常大的学问。通常情况下,用户应该尽可能选择有明确意义的英文单词作为变量名,尽量避免使用拼音或者毫无意义的字符串作为变量名。这样的话,用户通过变量名就可以了解该变量的作用。
例如,下面的变量名都是非常好的选择:
PATH=/sbin
UID=100
JAVA_HOME="/usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/../.."
SSHD=/usr/sbin/sshd

3.1.3  变量的类型
Shell是一种动态类型语言和弱类型语言,即在Shell中,变量的数据类型毋需显示地声明,变量的数据类型会根据不同的操作有所变化。准确地讲,Shell中的变量是不分数据类型的,统一地按照字符串存储。但是根据变量的上下文环境,允许程序执行一些不同的操作,例如字符串的比较和整数的加减等等。
#! /bin/bash

#定义变量x,并且赋值为123
x=123
#变量x加1
let "x += 1"
#输出变量x的值
echo "x = $x"
#显示空行
Echo
#替换x中的1为abc,并且将值赋给变量y
y=${x/1/abc}
#输出变量y的值
echo "y = $y"
#声明变量y
declare -i y
#输出变量y的值
echo "y = $y"
#变量y的值加1
let "y += 1"
#输出变量y的值
echo "y = $y"
#显示空行
echo
#将字符串赋给变量z
z=abc22
#输出变量z的值
echo "z = $z"
#替换变量z中的abc为数字11,并且将值赋给变量m
m=${z/abc/11}
#输出变量m的值
echo "m = $m"
#变量m加1
let "m += 1"
#输出变量m的值
echo "m = $m"
echo
#将空串赋给变量n
n=""
#输出变量n的值
echo "n = $n"
#变量n加1
let "n += 1"
echo "n = $n"
echo
#输出空变量p的值
echo "p = $p"
# 变量p加1
let "p += 1"
echo "p = $p"

[root@linux chapter3]# ./ex3-1.sh
x = 124

y = abc24
y = abc24
y = 1

z = abc22
m = 1122
m = 1123

n =
n = 1

p =
p = 1

3.1.4  变量的定义
在Shell中,通常情况下用户可以直接使用变量,而毋需先进行定义,当用户第一次使用某个变量名时,实际上就同时定义了这个变量,在变量的作用域内,用户都可以使用该变量。

#! /bin/bash   
               
#定义变量a     
a=1            
#定义变量b     
b="hello"      
#定义变量c     
c="hello world"

通过declare命令声明变量
declare attribute variable

-p:显示所有变量的值。
-i:将变量定义为整数。在之后就可以直接对表达式求值,结果只能是整数。如果求值失败或者不是整数,就设置为0。
-r:将变量声明为只读变量。只读变量不允许修改,也不允许删除。
-a:变量声明为数组变量。但这没有必要。所有变量都不必显式定义就可以用作数组。事实上,在某种意义上,似乎所有变量都是数组,而且赋值给没有下标的变量与赋值给下标为0的数组元素相同.
-f:显示所有自定义函数,包括名称和函数体。
-x:将变量设置成环境变量,这样在随后的脚本和程序中可以使用。
#! /bin/bash

定义变量x,并将一个算术式赋给它
x=6/3
echo "$x"
#定义变量x为整数
declare -i x
echo "$x"
#将算术式赋给变量x
x=6/3
echo "$x"
#将字符串赋给变量x
x=hello
echo "$x"
#将浮点数赋给变量x
x=3.14
echo "$x"
#取消变量x的整数属性
declare +i x
#重新将算术式赋给变量x
x=6/3
echo "$x"
#求表达式的值
x=$[6/3]
echo "$x"
#求表达式的值
x=$((6/3))
echo "$x"
#声明只读变量x
declare -r x
echo "$x"
#尝试为只读变量赋值
x=5
echo "$x"

[root@linux chapter3]# ./ex3-3.sh
6/3
6/3
2
0
./ex3-3.sh: line 15: 3.14: syntax error: invalid arithmetic operator (error token is ".14")
0
6/3
2
2
2
./ex3-3.sh: line 32: x: readonly variable
2

3.1.5  变量和引号
Shell语言中一共有3种引号,分别为单引号(' ')、双引号(" ")和反引号(` `)。
这3种引号的作用是不同的,其中
    单引号   所有字符都将保留字面意义;
    双引号   除$\'和"之外的其余字符都将保留字面意义;
    反引号   反引号中的字符串被解释为shell命令;

    反斜线   转义字符,屏蔽后面字符的特殊意义;

#! /bin/bash

#输出当前目录
echo "current directory is `pwd`"
[root@linux chapter3]# ./ex3-4.sh
current directory is /root/chapter3

3.1.6  变量的作用域
Shell中的变量也分为全局变量和局部变量2种
全局变量可以在脚本中定义,也可以在某个函数中定义。在脚本中定义的变量都是全局变量,其作用域为从被定义的地方开始,一直到Shell脚本结束或者被显式地删除
#! /bin/bash

#定义函数
func()
{
   #输出变量x的值
   echo "$v1"
   #修改变量x的值
   v1=200

}
#在脚本中定义变量x
v1=100
#调用函数
func
#输出变量x的值
echo "$v1"
[root@linux chapter3]# ./ex3-5.sh
100
200
#! /bin/bash

#定义函数
func()
{
   #在函数内部定义变量
   v2=200

}
#调用函数
func
#输出变量的值
echo "$v2"[root@linux chapter3]# ./ex3-6.sh
200

与全局变量相比,局部变量的使用范围较小,通常仅限于某个程序段访问,例如函数内部。在Shell语言中,可以在函数内部通过local关键字定义局部变量,另外,函数的参数也是局部变量。
#! /bin/bash

#定义函数
func()
{
   #使用local关键字定义局部变量
   local v2=200

}
#调用函数
func
#输出变量的值
echo "$v2"
[root@linux chapter3]# ./ex3-7.sh
 
#! /bin/bash

#定义函数
func()
{
   #输出全局变量v1的值
   echo "global variable v1 is $v1"
   #定义局部变量v1
   local v1=2
   #输出局部变量v1的值
   echo "local variable v1 is $v1"

}
#定义全局变量v1
v1=1
#调用函数
func
#输出全局变量v1的值
echo "global variable v1 is $v1"
[root@linux chapter3]# ./ex3-8.sh
global variable v1 is 1
local variable is 2
global variable is 1
3.1.7  系统变量
Shell语言的系统变量主要在对参数判断和命令返回值判断时使用,包括脚本和函数的参数以及脚本和函数的返回值

$#   命令行参数的个数
$0   当前脚本的名称
$*   以"参数1 参数2 参数3 ..."的形式返回所有参数的值
$@   以"参数1""参数2""参数3"...的形式返回所有参数的值
$n   表示传递给脚本的第n个参数,例如$1表示第一个参数,$2表示第二个参数
$$   返回本进程的PID
$?   前一个命令或函数的返回状态码

#! /bin/bash

#输出脚本的参数个数
echo "the number of parameters is $#"
#输出上一个命令的退出状态码
echo "the return code of last command is $?"
#输出当前脚本名称
echo "the script name is $0"
#输出所有的参数
echo "the parameters are $*"
#输出其中的几个参数
echo "\$1=$1;\$2=$2;\$11=$11"

[root@linux chapter3]# ./ex3-9.sh a b c d e f g h i j k l m n
the number of parameters is 14
the return code of last command is 0
the script name is ./ex3-9.sh
the parameters are a b c d e f g h i j k l m n
$1=a;$2=b;$11=a1

3.1.8  环境变量
Shell的环境变量是所有的Shell程序都可以使用的变量。Shell程序在运行时,都会接收一组变量,这组变量就是环境变量。环境变量会影响到所有的脚本的执行结果。
PATH          命令搜索路径,以冒号为分割符
HOME          用户宿主目录的路径名,cd的默认参数
COLUMNS       定义了命令编辑模式下可使用命令的长度
HISTFILE      命令历史文件
HISTSIZE      命令历史文件最多可包含的命令条数
HISTFILESIZE  命令历史文件中包含的最大行数
IFS           定义SHELL使用的分割符
LOGNAME       当前登录名
SHELL         shell的全路径
TERM          终端类型
TMOUT         shell自动退出的时间(秒)若为0则禁止自动退出
PWD           当前工作目录
除了上表列出的环境变量之外,用户还可以使用set命令列出当前系统的环境变量。

[root@linux chapter3]# set | more
BASH=/bin/bash
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_EXECUTION_STRING='(set|more) >/tmp/vRTvQkj/1 2>&1'
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="25" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
BASH_VERSION='4.2.25(1)-release'
IFS=$' \t\n'
LANG=en_US.UTF-8
LANGUAGE=en_US:en
MACHTYPE=x86_64-pc-linux-gnu
OPTIND=1
OSTYPE=linux-gnu
SHELL=/bin/bash
TERM=xterm
UID=1000
VIM=/usr/share/vim
VIMRUNTIME=/usr/share/vim/vim73


#! /bin/bash

#输出命令搜索路径
echo "commands path is $PATH"
#输出当前的登录名
echo "current login name is $LOGNAME"
#输出当前用户的主目录
echo "current user's home is $HOME"
#输出当前的Shell
echo "current shell is $SHELL"
#输出当前工作目录
echo "current path is $PWD"

[root@linux chapter3]# ./ex3-10.sh
commands path is /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/pgsql-9.2/bin
current login name is root
current user's home is /root
current shell is /bin/bash
current path is /root/chapter3

3.2  变量赋值和和清空
3.2.1  变量赋值
在Shell中,变量的赋值使用以下语法:
variable_name=value
其中,varibale_name表示变量名,value表示变量的值。
例如,下面都是一些正确的赋值语句:
v1=Linux
v2='RedHat Linux'
v3="RedHat Linux $HOSTTYPE"
v4=12345
3.2.2  引用变量的值
在Shell中,用户可以通过在变量名前面加上“$”,来获取该变量的值。
#!/bin/bash

v1=Linux
v2='RedHat Linux'
v3="RedHat Linux $HOSTTYPE"
v4=12345
#输出变量v1的值
echo "$v1"
#输出变量
echo "$v2"
#输出变量v3的值
echo "$v3"
#输出变量v4的值
echo "$v4"
[root@linux chapter3]# ./ex3-11.sh
Linux
RedHat Linux
RedHat Linux x86_64
12345

3.2.3  清除变量
当某个Shell变量不再需要时,可以将其清除。当变量被清除后,其所代表的值也会消失。清除变量使用unset语句,其基本语法如下:
unset variable_name
其中,参数varibale_name表示要清除的变量的名称。

#! /bin/bash

#定义变量v1
v1="Hello world"
#输出v1的值
echo "$v1"
#清除变量
unset v1
echo "the value of v1 has been reset"
#再次输出变量的值
echo "$v1"

[root@linux chapter3]# ./ex3-12.sh
Hello world
the value of v1 has been reset

3.3  引用和替换
变量的引用和替换是Shell对于变量功能的扩展。
3.3.1  引用
所谓引用,是指将字符串用引用符号包括起来,以防止其中的特殊字符被Shell解释为其他涵义。特殊字符是指除了字面意思之外还可以解释为其他意思的字符。例如在Shell中,“$”符号的本身涵义是美元符号,其ASCII码值为十进制36。除了这个涵义之外,前面已经讲过,“$”符号还可以用了获取某个变量的值,即变量替换。星号“*”也是一个特殊的字符,星号可以用来作为通配符使用。

    单引号   所有字符都将保留字面意义;
    双引号   除$\'和"之外的其余字符都将保留字面意义;
    反引号   反引号中的字符串被解释为shell命令;
    反斜线   转义字符,屏蔽后面字符的特殊意义;

3.3.2  全引用
在Shell语句中,当一个字符串被单引号引用起来之后,其中所有的字符,除单引号本身之外,都将被解释为字面意义,即字符本身的涵义。这意味着被单引号引用起来的所有的字符都将被解释为普通的字符,因此,这种引用方式称为全引用。
#! /bin/bash

#定义变量v1
v1="chunxiao"
#输出含有变量名的字符串
echo 'Hello, $v1'

[root@linux chapter3]# ./ex3-14.sh
Hello, $v1

3.3.3  部分引用
对于单引号来说, 被其引用起来的所有的字符都将被解释为字面意义。
而对于双引号来说,情况会有所不同。
如果用户使用双引号将字符串引用起来,则其中所包含的字符除美元符号($)、反引号(`)以及反斜线(\)之外的所有的其他的字符,都将被解释为字面意义,这称为部分引用。
也就是说,在部分引用中,“$”、“`”和“\”仍然拥有特殊的涵义。
#! /bin/bash

#定义变量
v1="chunxiao"
#输出变量的值
echo "Hello, $v1"

[root@linux chapter3]# ./ex3-15.sh
Hello, chunxiao

3.3.4  命令替换
所谓命令替换,是指在Shell程序中,将某个Shell命令的执行结果赋给某个变量。在bash中,有2种语法可以进行命令替换,分别使用反引号和圆括号,如下:
`shell_command`
$(shell_command)
以上2种语法时等价的,推荐使用后一种,用户可以根据自己的习惯来选择使用。
使用eval命令可以让后面的字符串作为命令重复解析一次;
#! /bin/bash

#变量替换
v1=`pwd`
#输出变量的值
echo "current working directory is $v1"

[root@linux chapter3]# ./ex3-16.sh
current working directory is /root/chapter3

3.3.5  转义
顾名思义,转义的作用是转换某些特殊字符的意义。转义使用反斜线表示,当反斜线后面的一个字符具有特殊的意义时,反斜线将屏蔽该字符的特殊意义,使得Shell按照该字符的字面意义来解释。

[root@linux chapter3]# echo $SHELL
/bin/bash
[root@linux chapter3]# echo \$SHELL
$SHELL

0 0
原创粉丝点击