二十三. Bash Shell编程:
1. 读取用户变量:
read命令是用于从终端或者文件中读取输入的内建命令,read命令读取整行输入,每行末尾的换行符不被读入。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY。下面的列表给出了read命令的常用方式:
命令格式 |
描述 |
read answer |
从标准输入读取输入并赋值给变量answer。 |
read first last |
从标准输入读取输入到第一个空格或者回车,将输入的第一个单词放到变量first中,并将该行其他的输入放在变量last中。 |
read |
从标准输入读取一行并赋值给特定变量REPLY。 |
read -a arrayname |
把单词清单读入arrayname的数组里。 |
read -p prompt |
打印提示,等待输入,并将输入存储在REPLY中。 |
read -r line |
允许输入包含反斜杠。 |
见下面的示例(绿色高亮部分的文本为控制台手工输入信息):
/> read answer #等待读取输入,直到回车后表示输入完毕,并将输入赋值给变量answer
Hello #控制台输入Hello
/> echo $answer #打印变量
Hello
#等待一组输入,每个单词之间使用空格隔开,直到回车结束,并分别将单词依次赋值给这三个读入变量。
/> read one two three
1 2 3 #在控制台输入1 2 3,它们之间用空格隔开。
/> echo "one = $one, two = $two, three = $three"
one = 1, two = 2, three = 3
/> read #等待控制台输入,并将结果赋值给特定内置变量REPLY。
This is REPLY #在控制台输入该行。
/> echo $REPLY #打印输出特定内置变量REPLY,以确认是否被正确赋值。
This is REPLY
/> read -p "Enter your name: " #输出"Enter your name: "文本提示,同时等待输入,并将结果赋值给REPLY。
Enter you name: stephen #在提示文本之后输入stephen
/> echo $REPLY
stephen
#等待控制台输入,并将输入信息视为数组,赋值给数组变量friends,输入信息用空格隔开数组的每个元素
/> read -a friends
Tim Tom Helen
/> echo "I have ${#friends} friends"
I have 3 friends
/> echo "They are ${friends[0]}, ${friends[1]} and ${friends[2]}."
They are Tim, Tom and Helen.
2. 状态判断:
test是Shell中提供的内置命令,主要用于状态的检验,如果结果为0,表示成功,否则表示失败。见如下示例:
/> name=stephen
/> test $name != stephen
/> echo $?
1
需要注意的是test命令不支持Shell中提供的各种通配符,如:
/> test $name = [Ss]tephen
/> echo $?
1
test命令还可以中括号予以替换,其语义保持不变,如:
/> [ $name = stephen ]
/> echo $?
0
在Shell中还提供了另外一种用于状态判断的方式:` expr `,和test不同的是,该方式中的表达式支持通配符,如:
/> name=stephen
/> [[ $name == [Ss]tephen ]]
/> echo $?
0
#在` expression `中,expression可以包含&&(逻辑与)和||(逻辑或)。
/> [[ $name == [Ss]tephen && $friend == "Jose" ]]
/> echo $?
1
/> shopt -s extglob #打开Shell的扩展匹配模式。
/> name=Tommy
# "[Tt]o+(m)y"的含义为,以T或t开头,后面跟着一个o,再跟着一个或者多个m,最后以一个y结尾。
/> [[ $name == [Tt]o+(m)y ]]
/> echo $?
0
在Shell中还提供了let命令的判断方式: (( expr )),该方式的expr部分,和C语言提供的表达式规则一致,如:
/> x=2
/> y=3
/> (( x > 2 ))
/> echo $?
1
/> (( x < 2 ))
/> echo $?
0
/> (( x == 2 && y == 3 ))
/> echo $?
0
/> (( x > 2 || y < 3 ))
/> echo $?
1
下面的表格是test命令支持的操作符:
判断操作符 |
判断为真的条件 |
字符串判断 |
|
[ stringA=stringB ] |
stringA等于stringB |
[ stringA==stringB ] |
stringA等于stringB |
[ stringA!=stringB ] |
stringA不等于stringB |
[ string ] |
string不为空 |
[ -z string ] |
string长度为0 |
[ -n string ] |
string长度不为0 |
逻辑判断 |
|
[ stringA -a stringB ] |
stringA和stringB都是真 |
[ stringA -o stringB ] |
stringA或stringB是真 |
[ !string ] |
string不为真 |
逻辑判断(复合判断) |
|
[[ pattern1 && pattern2 ]] |
pattern1和pattern2都是真 |
[[ pattern1 || pattern2 ] |
pattern1或pattern2是真 |
[[ !pattern ]] |
pattern不为真 |
整数判断 |
|
[ intA -eq intB ] |
intA等于intB |
[ intA -ne intB ] |
intA不等于intB |
[ intA -gt intB ] |
intA大于intB |
[ intA -ge intB ] |
intA大于等于intB |
[ intA -lt intB ] |
intA小于intB |
[ intA -le intB ] |
intA小于等于intB |
文件判断中的二进制操作 |
|
[ fileA -nt fileB ] |
fileA比fileB新 |
[ fileA -ot fileB ] |
fileA比fileB旧 |
[ fileA -ef fileB ] |
fileA和fileB有相同的设备或者inode值 |
文件检验 |
|
[ -d $file ] or [[ -d $file ]] |
file为目录且存在时为真 |
[ -e $file ] or [[ -e $file ]] |
file为文件且存在时为真 |
[ -f $file ] or [[ -f $file ]] |
file为非目录普通文件存在时为真 |
[ -s $file ] or [[ -s $file ]] |
file文件存在, 且长度不为0时为真 |
[ -L $file ] or [[ -L $file ]] |
file为链接符且存在时为真 |
[ -r $file ] or [[ -r $file ]] |
file文件存在且可读时为真 |
[ -w $file ] or [[ -w $file ]] |
file文件存在且可写时为真 |
[ -x $file ] or [[ -x $file ]] |
file文件存在且可执行时为真 |
注:在逻辑判断(复合判读中),pattern可以包含元字符,在字符串的判断中,pattern2必须被包含在引号中。
let命令支持的操作符和C语言中支持的操作符完全相同,如:
+,-,*,/,% 加,减,乘,除,去模
>>,<< 右移和左移
>=,<=,==,!= 大于等于,小于等于,等于,不等于
&,|,^ 按位与,或,非
&&,||,! 逻辑与,逻辑或和取反
还有其含义和C语言等同的快捷操作符,如=,*=,/=,%=,+=,-=,<<=,>>=,&=,|=,^=。