shell 中变量的类型分为:本地变量、环境变量、位置变量、特殊变量;
环境变量是用于设置系统运行环境的变量,在 shell 的所有用户进程可用,通常称之为全局变量;环境变量的名称一般是由大写字母组成,例如:
#HOME变量,用户主目录的全路径名;
echo $HOME
#PATH变量,定义一些目录路径;
echo $PATH
#PWD变量,当前工作目录的绝对路径;
echo $PWD
位置变量是依据出现在命令行上的参数的位置来确定的变量,通常被 shell 脚本用来从命令行接受参数,或被函数用来保存传递给它的参数。执行 shell 脚本时,用户可以通过命令行向脚本传递信息,跟在脚本名后面的用空格隔开的每个字符串都称为位置变量。如下所示:
$命令 参数1 参数2 参数3 ...
具体有如下的位置变量:
位置变量 | 具体含义 |
---|---|
$0 | 当前执行的命令或shell程序的文件名 |
$1 | 表示第1个位置参数 |
$2 | 表示第2个位置参数 |
… | … |
$9 | 表示第9个位置参数 |
${10} | 从第10个参数开始必须使用大括号 |
例如:
#!/bin/bash
#filename:test.sh
echo "shell程序文件名为: $0"
echo "第1个位置参数: $1"
echo "第2个位置参数: $2"
echo "第3个位置参数: $3"
echo "第4个位置参数: $4"
echo "第5个位置参数: $5"
执行test.sh
文件:
$ sh test.sh linux shell bash learn ubuntu
shell程序文件名为: test.sh
第1个位置参数: linux
第2个位置参数: shell
第3个位置参数: bash
第4个位置参数: learn
第5个位置参数: ubuntu
特殊变量与环境变量相类似,由 shell 根据实际情况来设置,这些变量具有特殊的含义,用户不能重新设置该值,所有特殊变量都由$
符号与另一个符号组成,常见的特殊变量如下表所示:
特殊变量 | 具体含义 |
---|---|
$# | 实际位置参数的个数 |
$* | 命令行中所有位置参数组成的字符串 |
$! | 上一个后台命令对应的进程ID号 |
$$ | 表示当前运行脚本的进程ID号 |
$? | 表示最后命令运行后的退出状态 |
本地变量是用户自定义的变量,变量的命名规则跟其他高级语言类似,必须以字母或下划线开头,后面接字母、下划线或数字;变量名对大小写字母敏感。局部变量定义格式如下:
local 变量名
shell中有两个内置命令 declare 和 typeset 可用于创建变量,通过命令的选项设置可以设定变量的创建方式,例如declare -r
创建只读变量;
declare attribute 变量名
其中attribute
表示属性,取值如下表所示:
属性 | 具体含义 |
---|---|
-p | 显示所有变量的值 |
-i | 定义整数变量 |
-r | 定义只读变量 |
-a | 定义数组变量 |
-f | 显示所有自定义函数 |
-x | 将变量设置为环境变量 |
除了两个内置命令外,也可通过直接赋予一个变量名来创建变量,为变量赋值时,变量前不必加$
符号,只有在使用该变量时才会使用$
符号;变量的创建如下:
变量名=变量值
注意:等号=
两边不能有空格,变量值内部有空格时,该变量值必须使用双引号;变量名不能与其他文字混在一起,若想要在变量名紧接文字时,必须使用大括号把变量名包起来;例如:
#!/bin/bash
#filename:test.sh
var=10 #变量var
y="usage [d] shell" #变量y
x=20
#显示变量的值
echo "the value of var is: $var"
echo "the value of y is: $y"
echo "the value of x is: ${x}th"
执行结果:
$ sh test.sh
the value of var is: 10
the value of y is: usage [d] shell
the value of x is: 20th
shell
支持三种引号方式:
$、\、'、"
这几个特殊符号保留其特殊功能之外,其他字符仍作为普通字符;使用shell的内部 unset 命令可以删除变量。语法:
unset variable_name
变量被删除后不能再次使用;unset 命令不能删除只读变量。例子:
#!/bin/sh
#filename:test.sh
var="http://blog.csdn.net/chenhanzhun"
echo -n "before use unset,the value of var:"
echo $var
unset var
echo -n "after use unset,the value of var:"
echo $var
执行结果:
$ sh test.sh
before use unset,the value of var:http://blog.csdn.net/chenhanzhun
after use unset,the value of var:
在shell 程序中,在定义变量的同时直接赋予初值;例如:
#!/bin/sh
#filename:test.sh
#直接给变量赋值
var="http://blog.csdn.net/chenhanzhun"
read 是 shell 的内部命令,可以从标准输入设备或从一个文件读取数据,read 命令读取一个输入行直到遇到换行符为止,其语法格式如下:
#把读入的数据依次赋值给:变量1、变量2、变量3、...
read 变量1 变量2 变量3 ...
read 命令的赋值规则如下:
若没有指定变量来保存 read 所输入的内容,则 bash 会把输入的数据保存在 REPLY 的变量中,另外 read 加上参数 -p 可以提示信息,即read -p
;
例如:
#!/bin/sh
#filename:test.sh
echo -n "please enter your name and telephone number: "
read var1 var2
echo -n "you had enter your name are: "
echo $var1
echo -n "you had enter your NO. is: "
echo $var2
read -p "the second, enter the value: "
echo -n "you had enter the value is: $REPLY"
执行结果:
$ sh test.sh
#情况1:变量个数与输入数据个数相等
please enter your name and telephone number: Linux 123456
you had enter your name are: Linux
you had enter your NO. is: 123456
#情况2:变量个数大于输入数据个数
please enter your name and telephone number: Linux
you had enter your name are: Linux
you had enter your NO. is:
#情况3:变量个数小于输入数据个数
please enter your name and telephone number: Linux 123456 shell 789
you had enter your name are: Linux
you had enter your NO. is: 123456 shell 789
#使用 -p 选项,并使用默认变量 REPLY
the second, enter the value: 16
you had enter the value is: 16
在 shell 中可以使用命令行参数给位置变量赋值;例如:
#!/bin/sh
#filename:test.sh
echo "first: $1"
echo "second: $2"
echo "third: $3"
#执行结果如下:
$ sh test.sh Linux Nginx C++
first: Linux
second: Nginx
third: C++
变量的输出由echo
或printf
命令完成,printf
命令跟 C
语言的类似,也可以格式化输出;
数组的定义格式如下所示:
数组名=(元素1 元素2 元素3 ...)
#例如:定义一个student数组
student=(one two three four)
例子:
#!/bin/bash
#filename:test.sh
student=(one two three four)
for i in 0 1 2 3
do
echo ${student[$i]}
done
#执行结果:
$ sh test.sh
one
two
three
four
${arr[num]} #数组下标为 num 的元素
${#arr[*]} #数组元素的个数
${#arr[num]} #数组下标为 num 的元素的长度
all=("${arr[*]}") #将数组arr的全部内容作为一个元素复制给数组all
all=("${arr[@]}") #将数组arr的全部内容复制给数组all
shell 中没有内置算术运算,不能直接做加、减、乘、除等算术运算;整数运算可以使用expr
命令或let
命令;浮点运算可以使用awk
命令或bc
命令。
expr
命令
expr
命令是一个表达式处理命令,当用来计算算术运算表达式时,它可以执行简单的整数操作,有 5 中算术运算符可以使用:+、-、\*、/、%
;在使用这些运算符时,运算符前后必须有空白,且只能用于整数运算;例如:
#!/bin/bash
#filename:test.sh
var=10
a=5
x=`expr $var / $a`
y=`expr $var % $a`
b=`expr $a + 4`
echo x=$x y=$y b=$b
#执行结果:
$ sh test.sh
x=2 y=0 b=9
let
命令
let
命令不需要在变量前面加$
符号,但必须将单个或带有空格的表达式用双引号引起来。例如:
#!/bin/bash
#filename:test.sh
var=10
a=5
let x=var/a
let y=var%a
let "b = a + 4"
c=`expr $a \* $var`
echo x=$x y=$y b=$b c=$c
#执行结果:
$ sh test.sh
x=2 y=0 b=9 c=50
bc
命令
例子:
#!/bin/bash
#filename:test.sh
n=`echo " scale=2; 172 / 2 " | bc `
echo $n
#执行结果:
86.00
#解析:
#反单引号:把反单引号里面的字符作为命令执行;
#scale=2 表示设置小数点后面保留2位;
#echo的结果通过管道命令传入给bc命令
awk
命令
例子:
#!/bin/bash
#filename:test.sh
var=` awk 'BEGIN {x=5.1;y=2; printf "%.2f %.3f" , x*y,x/y;}'`
echo $var
#执行结果:
$ sh test.sh
10.20 2.550
shell 脚本中提供了对数值、字符和文件的条件测试,测试结果若为0表示条件为真,若为非0表示条件为假。
shell
的测试命令条件测试有两种语法:test
命令和[]
命令;test
命令是shell 编程中条件判断最常用的测试命令,一般与if、while、until
命令一起使用,test
命令格式如下:
test 表达式
#test 命令也可以使用方括号代替,注意:方括号前后必须有空格
[ 表达式 ]
#例如:
x=5;y=8
test $x -gt $y
echo $?
[ $x -gt $y ]
echo $?
#执行结果:
$ sh test.sh
1
1
文件属性测试表达式是测试文件的属性状态,包括文件是否可写、可执行,文件是否存在;常用的文件测试表达式如下:
表达式 | 具体含义 |
---|---|
-b FILE | FILE exists and is block special |
-c FILE | FILE exists and is character special |
-d FILE | FILE exists and is a directory |
-e FILE | FILE exists |
-f FILE | FILE exists and is a regular file |
-g FILE | FILE exists and is set-group-ID |
-G FILE | FILE exists and is owned by the effective group ID |
-h FILE | FILE exists and is a symbolic link (same as -L) |
-k FILE | FILE exists and has its sticky bit set |
-L FILE | FILE exists and is a symbolic link (same as -h) |
-O FILE | FILE exists and is owned by the effective user ID |
-p FILE | FILE exists and is a named pipe |
-r FILE | FILE exists and read permission is granted |
-s FILE | FILE exists and has a size greater than zero |
-S FILE | FILE exists and is a socket |
-t FD | file descriptor FD is opened on a terminal |
-u FILE | FILE exists and its set-user-ID bit is set |
-w FILE | FILE exists and write permission is granted |
-x FILE | FILE exists and execute (or search) permission is granted |
例如:
#!/bin/bash
#filename:test.sh
echo -n "please enter the filename: "
read FILENAME
#测试文件是否存在
if test -e $FILENAME ; then
ls -l $FILENAME
else
touch $FILENAME
fi
#测试文件是否可执行
if test -x $FILENAME ; then
sh $FILENAME
else
chmod +x $FILENAME
ls -l $FILENAME
fi
#其他文件属性的测试类似上面
#执行结果
$ sh test.sh
please enter the filename: test.sh
-rw-rw-r-- 1 354 Mar 7 10:09 test.sh
-rwxrwxr-x 1 354 Mar 7 10:09 test.sh
数值测试包括:相等、不相等、大于、小于、不大于、不小于;常用的数值测试表达式如下表所示:
表达式 | 具体含义 |
---|---|
var1 -eq var2 | var1等于var2 |
var1 -ne var2 | var1不等于var2 |
var1 -gt var2 | var1大于var2 |
var1 -lt var2 | var1小于var2 |
var1 -ge var2 | var1大于等于var2 |
var1 -le var2 | var1小于等于var2 |
例如:
#!/bin/bash
#filename:test.sh
echo -n "please enter two number: "
read N1 N2
if test $N1 -eq $N2 ; then
echo "equal"
elif test $N1 -gt $N2 ; then
echo "greater"
else
echo "less"
fi
#执行结果:
$ sh test.sh
please enter two number: 15 20
less
字符测试包括:相等、不相等、长度是否为0、非空测试;常用的字符测试表达式如下表所示:
表达式 | 具体含义 |
---|---|
-z str | str长度为0 |
-n str | str长度不为0 |
str1 = str2 | str1 等于 str2 |
str1 != str2 | str1 不等于 str2 |
str | str不为空 |
例如:
#!/bin/bash
#filename:test.sh
echo -n "please enter str1: "
read str1
echo -n "please enter str2: "
read str2
if test $str1 = $str2; then
echo "equal"
else
echo "not equal"
fi
if test -z $str1; then
echo "the length of str1 is 0"
else
echo "the length of str1 is not 0"
fi
if test $str2; then
echo "str2 is not empty"
else
echo "str2 is empty"
fi
#执行结果:
$ sh test.sh
please enter str1: Linux
please enter str2: shell
not equal
the length of str1 is not 0
str2 is not empty
当测试命令由多个测试条件构成时,必须使用到逻辑符号进行测试,shell 提供了:非(!)、与(-a)、或(-o)逻辑运算符,其优先级一次递减:!、-a、-o;
例子:
#!/bin/bash
#filename:test.sh
echo -n "please enter the number: "
read a
if test $a -ge 10 -a $a -le 20; then
echo "10<= $a <=20"
else
echo "not between 10~20"
fi
#执行结果:
$ sh test.sh
please enter the number: 12
10<= 12 <=20
shell 提供了对多种流程控制结构的支持,包括:条件结构、分支结构、循环结构;
在shell中使用 if
语句来实现条件结构,其语法格式如下所示:
if 表达式
then
执行语句
elif 表达式;then #then与表达式在同一行时,必须在表达式后面加上分号
执行语句
elif 表达式
then
执行语句
else
执行语句
fi
#嵌套if语句
if 表达式;then
执行语句
else
if 表达式; then
执行语句
elif 表达式; then
执行语句
else
执行语句
fi
fi
其中,表达式是判断条件,若为真时,才执行 then
里面的执行语句;if
语句可以嵌套if
语句,嵌套语句相当于elif
;if
语句里面可以包含多个elif
,但是只能有一个else
语句;
分支结构case
语句是一个多路分支判断结构,可以测试一个表达式的值,并根据该值选择执行相应的分支程序;其语法格式如下所示:
case 表达式 in
模式1) 执行语句;; #若匹配到模式1时,先执行语句,然后 ;; 跳出case 语句
模式2) 执行语句;;
模式3) 执行语句;;
...
*) 执行语句;; #若上面的模式都不匹配时,则执行这里的语句
esac #结束case语句
#注意:case 语句和 if语句一样,也可以嵌套使用
select 循环结构
select
循环结构的语法格式如下所示:
select 变量 in 列表
do
执行语句
done
列表是由字符串组成的序列,执行select 语句时,该列表会以菜单形式进行显示,用户选择其中某一项之后,shell 会把该项赋值给变量,并执行select
结构体中的语句。例如:
#!/bin/bash
#filename:test.sh
echo "select the number: "
select N in one two three foure five six seven
do
case $N in
one) echo "one";;
two) echo "two";;
three) echo "three";;
foure) echo "foure";;
five) echo "five";;
six) echo "six";;
seven) echo "seven";;
*) echo "none"
break;;
esac
done
#执行结果:
$ sh test.sh
select the number:
1) one
2) two
3) three
4) foure
5) five
6) six
7) seven
#? 1
one
#? 5
five
#? 8
none
while
循环结构
while
循环结构的语法格式如下所示:
while 表达式
do
执行语句
done
#注意:while 语句里面可以嵌套 while 语句
例如:
#!/bin/bash
#filename:test.sh
echo "while: "
i=1
while [ $i -le 5 ]
do
echo "the ${i}th while;"
i=$(($i+1))
done
#执行结果
$ sh test.sh
while:
the 1th while;
the 2th while;
the 3th while;
the 4th while;
the 5th while;
for
循环结构
for
语句的语法格式如下所示:
for 变量 [ in 列表 ]
do
执行语句
done
例如:
#!/bin/bash
#filename:test.sh
echo "while: "
for i in 1 2 3 4
do
echo "the ${i}th while;"
done
#执行结果:
$ sh test.sh
while:
the 1th while;
the 2th while;
the 3th while;
the 4th while;
until
循环结构
until
循环结构是当条件为假时,执行语句,条件为真时,停止执行;其语法格式如下所示:
until
执行语句
test 表达式
do
执行语句
done
例如:
#!/bin/bash
#filename:test.sh
echo -n "enter the number: "
read N
i=1
until
test $i -gt $N
do
result=`expr $i \* $i`
echo "$i------$result"
i=$(($i+1))
done
#执行结果:
$ sh test.sh
enter the number: 5
1------1
2------4
3------9
4------16
5------25
函数的定义格式如下所示:
function 函数名 ()
{
执行语句
}
#或
函数名()
{
执行语句
}
函数调用格式如下所示:
函数名 参数1 参数2 ...
例如:
#!/bin/bash
#filename:test.sh
#定义函数
getcurrenttime()
{
curr_time=`date`
echo "$curr_time"
}
function show()
{
echo $a $b $c
echo $1 $2 $3
}
a=10
b=12
c=13
#调用函数
getcurrenttime
#调用函数并传递参数
show a b c
#执行结果:
$ sh test.sh
Sat Mar 7 16:00:38 CST 2015
10 12 13
a b c
若在函数想要返回值时,可使用return
,return
返回值只能是0~256
之间的一个整数,返回值保存在变量$?
中,若没有指定return
返回值,则返回的函数值是该函数最后一个执行命令的退出状态;
使用命令unset -f
可以从 shell 内存中删除函数,其格式如下所示:
unset -f 函数名