4. Shell变量的类型
??Shell中变量的类型分为环境变量、位置变量、预定义的特殊变量以及用户自定义变量,每个变量都有其特殊的功能。
??4.1 环境变量
??环境变量是一类Shell预定义变量,用于设置系统运行环境的变量。
??(1)HOME:用户主目录的全路径名。主目录是用户开始工作的位置,在一般情况下,如果用户名是 myname,HOME的值便是/home/myname。
[root@localhost~]# echo $ HOME
/home/myname
??注意:如果要使用环境变量或其他Shell变量的值,必须在变量名之前加上一个“ $ ”符号,如cd $ HOME,不能直接使用变量名。
??(2)PATH:变量PATH中定义了一些目录路径,路径由冒号分隔。在执行命令或Shell脚本时,Shell会按PATH变量中设定的顺序搜索这些目录,找到的第一个匹配的命令或Shell 脚本将被执行。
[root@localhost~]# echo $ PATH //显示变量 PATH 当前值
/usr/local/sbin:/usr/local/bin:/sbin:/bin:usr/sbin:/root/bin
??(3)PWD:当前工作目录的绝对路径。它指出当前在Linux文件系统中处于什么位置。它是由Linux自动设置的,会随cd命令的使用而改变,可以通过下列命令获得当前路径:
[root@localhost~]#echo $ PWD
/root
??(4)SHELL:定义Shell的解释器路径。例如,显示当前使用的shell解释器的绝对路径,命令如下所示。
[root@localhost~]# echo $ SHELL
/bin/bash
??4.2 位置变量
??位置变量是依据出现在命令上的参数的位置来确定的变量,参数的位置定义如下所示。
# 命令 参数1 参数 2参数3…
??位置变量对应命令行上各项位置参数,命令名对应 $ 0,命令的第一参数对应 $ 1,命令的第二参数对应 $ 2,依次类推。如有Shell脚本,其内容如下:
# filename:locat
echo $ 0 $ 1 $ 2 $ 3 $ 4 $ 5
shift
??带位置参数执行locat程序,如下所示。
[root@localhost~]# chmod u + x locat
[root@localhost~]# ./locat 1 2 3 4 5
??4.3 预定义的特殊变量
??预定义的特殊变量与环境变量类似,由shell根据实际情况来设置,其值不能由用户重新设置,所有的预定义特殊变量由“ $ ”符号与另一个符号组成。
??$ #:实际位置参数个数。
??$ *:命令行中的所有位置参数组成的字符串。
??$ !:上一个后台命令对应的进程号。
??$ ?:表示最近一条命令执行后的退出状态,为十进制数。
??$ $:当前进程号PID。
??例如,编写Shell程序’mydefine,文件内容如下所示。
echo $ #
echo $ *
??带参数执行mydefine程序,如下所示:
[root@localhost~]# chmod u + x mydefine
[root@localhost~]# ./mydefine A B C D
4
ABCD
??4.4 用户自定义的变量
??变量的名称由字母或下划线开头,后面是任意的字母数字、下划线,为了使变量名和命令名相区别,一般变量名用大写字母来表示。
5.Shell变量的赋值
??5.1 使用read命令赋值
??read命令是一个内置命令,可以从标准输入设备或从一个文件读取数据。read命令读取一个输入行直到遇到一个换行符为止。
格式:read 变量1 变量2…
??例如,在readtest脚本中使用read命令将用户的输入保存在变量test中,然后通过echo命令显示输出,程序代码如下:
# !/bin/bash
# filename:readtest
echo -n "请输入一个名字"
read name
echo "你输入的用户名为:$ name"
??执行过程如下:
//赋予文件readtest执行权限
[root@localhost~]# chmod u + x readtest
//执行程序readtest
[root@localhost~]# ./readtest
//从键盘上输人张三
请输人您的用户名:张三
你输人的用户名:张三
??5.2 直接给变量赋值
??在Shell程序中,定义变量的同时可以直接给变量赋值。变量名前不应加美元符号“$”,且等号前后不可有空格。
??例如,下面的脚本程序resume定义了变量NAME、GENDER,并依次赋值“Sulivan”、“male”,最后通过echo命令显示输出变量的值,代码如下:
# !/bin/bash
# filenane:resume
NAME = Sulivan
GENDER = male
echo "name: $ NAME"
echo "gender: $ GRNDER"
??其中,代码3、4行依次对变量NAME、GENDER直接赋值,执行程序resume,显示结果如下:
[root@localhost~]# ./resume
name:sulivan
gender :male
??5.3 使用命令行参数赋值
??用户可以通过使用命令行参数对位置变量赋值,如脚本程序cmdarg内容如下:
# !/bin/bash
# filename:cmdarg
echo "program name: $ 0"
echo "you first argument: $ 1"
echo "you second argument: $ 2"
??其中,代码第3~5行实现了对应位置参数的输出。
[root@localhost~]# chomd u + x cmdarg
[root@localhost~]# ./cmdarg 555 666
??程序显示的结果是:
program name: . /cmdarg
you first argument:555
you second argument:666
6.Shell变量的输出
??命令格式为:
echo $ name1 [ $ name2]
??其中,$ namel、$ name2表示输出的变量,引用变量时需要在变量名前添加$符号。
??例如,从标准读入变量VARNUMBER1、VARNUMBER2的值,通过echo命令显示输出变量的值。
[root@localhost~]# read VARNUMBER1 VARNUMBER2
aaa bbb
[root@localhost~]# echo $ VARNUMBER1
aaa
[root@localhost~]# echo $ VARNUMBER2
bbb
7.Shell的算术运算
??Shell没有内置的算术运算符号,不能直接做加、减、乘、除运算。
??7.1 expr 命令
??expr命令是一个表达式处理命令,当计算算术运算表达式时,可以执行简单的整数运算,有“+、一、*、/、%”等相关操作。
??例如,在Shell提示符下执行如下命令:
[root@localhost~]# a=5;b=6
[root@localhost~]# a='expr $ a + 1'/ /注意赋值号右边为反引号,并且+运算符左右各有一空格
[root@localhost~]# echo $ a
6
??7.2 let命令
??let语句不需要在变量前面加美元符号 $,但必须将单个或带有空格的表达式用双引号引起来。
??例如,使用let命令完成简单的算术运算:
[root@localhost~]# x=100
[root@localhost~]# let "x=x+1"
[root@localhost~]# echo $ x
101
8.Shell的条件测试
??写脚本时,有时要判断字符串是否相等,可能还要检查文件状态或是数字测试,基于这些测试才能做进一步动作。test命令用于测试字符串、文件状态和数字。
??8.1 测试文件属性
??测试时使用的选项参数如表所示。
表达式 | 说明 |
---|
-b file | 如果文件file存在且为块设备,则值为真 | -c file | 如果文件file存在且为字符设备,则值为真 | -r file | 如果文件file存在且为只读,则值为真 | -w file | 如果文件file存在且为可写入,则值为真 | -x file | 如果文件file存在且为可执行,则值为真 | -s file | 如果文件file存在且为长度大于0,则值为真 | -d file | 如果文件file是一个目录,则值为真 | -f file | 如果文件file是一个普通文件,则值为真 | -e file | 如果文件file存在,则值为真 |
??例如,编写Shell程序testfile,测试变量指定的文件是否是字符设备,如果是则复制到/temp目录下,否则显示“ $ FILENAME is not a char device”,测试表达式为“test -c $ FILENAME”,程序内容如下所示。
# !/bin/bash
# filename:testfile
echo ”请输入文件的名字”
read FILENAME
if test - c $ FILENAME; then
cp $ FILENAME /temp
else
echo " $ FILENAME is not a char device"
fi
??该程序执行过程如下所示。
# chmod u + x testfile
# ./testfile
请输入文件的名字:
rc.local
rc.local is not a char device
??8.2 测试数值
??数值的测试包括相等测试、不相等测试、大于测试、大于等于测试、小于测试和小于等于测试,如表所示。
表达式 | 说明 |
---|
n1 -eq n2 | n1等于n2,则值为真 | n1 -ne n2 | n1不等于n2,则值为真 | n1 -gt n2 | n1大于n2,则值为真 | n1 -lt n2 | n1小于n2,则值为真 | n1 -ge n2 | n1大于等于n2,则值为真 | n1 -le n2 | n1小于等于n2,则值为真 |
??例如编写Shell程序noequal,测试变量N1和N2的值是否相等,如果相等,显示“equal”,否则显示“not equal”。测试表达式为“test $ N1-ne $ N2”,程序代码如下所示。
# !/bin/bash
# filename:noequal
echo "please enter the first number"
read N1
echo "please enter the second number"
read N2
if test $ N1 - ne $ N2;then
echo "not equal"
else
echo "equal"
fi
??代码第4行,第6行读入两个数值,且保存在变量N1和N2中,使用“-ne”对变量N1和N2所表示的两个数值是否相等进行判断,程序执行如下:
[root@localhost~]# chmod u + x noequal
please enter the first number:
45
please enter the second number:
67
not equal
??8.3 测试字符串
??字符串测试包括相等测试、不相等测试、长度为零测试、长度不为零测试以及非空测试,测试选项如表所示。
表达式 | 说明 |
---|
-z s1 | 如果字符串s1的长度为零,则值为真 | -n s1 | 如果字符串s1的长度不为零,则值为真 | s1 = s2 | 如果字符串s1与字符串s2相等,则值为真 | s1 ! = s2 | 如果字符串s1与字符串s2不相等,则值为真 | s1 | 如果字符串s1不是空串,则值为真 |
??例如,编写Shell程序noequal,测试变量S1和S2的值是否相等,如果相等,显示“equal”,否则显示“not equal”。测试表达式为“test $ S1= $ S2”,程序代码如下所示。
# !/bin/bash
# filename:noequal
echo "please enter the first string"
read S1
echo "please enter the second string"
read S2
if test $ S1!= $ S2;then
echo "not equal"
else
echo "equal"
fi
??代码第4行,第6行读入两个字符串,且保存在变量S1和S2中,使用“!=”对变量S1和S2所表示的两个字符串是否相等进行判断,执行过程如下所示。
[root@localhost~]# chmod u + x noequal
[root@localhost~]# ./noequal
please enter the first string:
jklmn
please enter the second string:
jklmn
equal
??8.4 测试逻辑运算符
??有关测试选项如表所示。
逻辑操作符 | 说明 |
---|
-a | 二进制“与”操作符 | -o | 二进制“或”操作符 | ! | 一元“非”操作符 |
??例如,编写Shell程序myand,测试变量Z的值是否大于等于10且小于等于50,如果满足条件则显示“between 20 and 40”,否则显示“not between 20 and 40”,程序代码如下:
# /bin/bash
# filename:myand
read Z
if test $ x -ge 20 - a $ x - le 40;then
echo "between 20 and 40"
else
echo "not between 20 and 40"
fi
??代码第4行使用-a对变量Z是否大于等于20且小于等于40进行测试,程序执行过程如下:
[root@localhost~]# chmod u + x myand
[root@localhost~]# ./myand
35
between 20 and 40
|