1. 分支语句
① 使用if-then语句
1
2
3
4
|
if command
then
commands
fi
|
注意,和c语言不同,bash shell的if语句会运行if后面的那个命令。如果该命令的退出状态码是0,位于then部分的命令就会被执行。如果该命令的退出状态码是其他值,then部分的命令就不会被执行,bash shell会继续执行脚本中下一个命令。fi语句用来表示if-then语句到此结束。
② test命令
如果test命令中列出的条件成立,test命令就会退出并返回退出状态码0。如果条件不成立,test命令就会退出并返回非零的退出状态码。
bash shell还提供了另一种条件测试方法,使用[]替代test命令。
1
2
3
4
|
if [ condition ] # 第一个方括号之后和第二个方括号之前必须加上一个空格。
then
commands
fi
|
test命令可以判断三类条件:数值比较,字符串比较,文件比较。注意,test中不能使用浮点数
test命令的数值比较功能
比较 |
描述 |
n1 -eq n2 |
检查n1是否与n2相等 |
n1 -ge n2 |
检查n1是否大于或等于n2 |
n1 -gt n2 |
检查n1是否大于n2 |
n1 -le n2 |
检查n1是否小于或等于n2 |
n1 -lt n2 |
检查n1是否小于n2 |
n1 -ne n2 |
检查n1是否不等于n2 |
test命令的字符串比较功能
比较 |
描述 |
str1 = str2 |
检查str1是否和str2相同 |
str1 != str2 |
检查str1是否和str2不同 |
str1 \< str2 |
检查str1是否比str2小,脚本会把<和>看做重定向符号,所以需要转义 |
str1 \> str2 |
检查str1是否比str2大 |
-n str1 |
检查str1的长度是否非0 |
-z str1 |
检查str1的长度是否为0 |
注意,在进行字符串比较的时候,test命令处理大写字母的方法刚好和sort命令相反。在test中,大写字母被认为是小于小写字母的。test使用的是标准的ASCII顺序,根据每个字符的ASCII数值来决定排序结果。sort命令使用的是系统的本地化语言设置中定义的排序顺序。对于英文,本地化设置指定了在排序顺序中小写字母出现在大写字母前。
test命令的文件比较功能
比较 |
描述 |
-b file |
file is a block device |
-d file |
检查file是否存在并是一个目录 |
-e file |
检查file是否存在 |
-f file |
检查file是否存在并是一个文件 |
-r file |
检查file是否存在并可读 |
-s file |
检查file是否存在并非空 |
-w file |
检查file是否存在并可写 |
-x file |
检查file是否存在并可执行 |
-O file |
检查file是否存在并属当前用户所有 |
-G file |
检查file是否存在并且默认组与当前用户相同 |
file1 -nt file2 |
检查file1是否比file2新 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
device0="/dev/sda2" # / (root directory)
# -b表示块设备
if [ -b "$device0" ]
then
echo "$device0 is a block device."
fi
device1="/dev/tty$1" # PCMCIA modem card
# -c表示字符设备
if [ -c "$device1" ]
then
echo "$device1 is a character device."
fi
function show_input_type()
{
# -p表示管道
[ -p /dev/fd/0 ] && echo PIPE || echo STDIN
}
show_input_type "Input"
echo "Input" | show_input_type
|
复合条件测试
1
2
|
与: [ condition1 ] && [ condition2 ]
或: [ condition1 ] || [condition2]
|
-a logical and
exp1 -a exp2
returns true if both exp1 and exp2 are true.
-o logical or
exp1 -o exp2
return true if either exp1 or exp2 is true.
There are similar to the Bash comparison operators && and || , used within double brackets.
[[ condition1 && condition2 ]]
The -o and -a operators work with the test command or occur within single test brackets.
1
2
3
4
5
6
|
if [ "$expr1" -a "$expr2" ]
then
echo "Both expr1 and expr2 are true."
else
echo "Either expr2 or expr2 is false."
fi
|
In a compound test, even quoting the string variable might not suffice(不够) .
[ -n “$string” -o “$a” = “$b” ] may cause an error with some versions of Bash if $string is empty.
The safe way is to append an extra character to possibly empty variables, [ “x$string” != x -o “x$a” = “x$b” ]
2. case命令
1
2
3
4
5
|
case variable in
pattern1 | pattern2) command1;;
pattern3) command2;;
*) default command;;
esac
|
3. 循环命令
3.1 for命令
1
2
3
4
|
for var in list
do
commands
done
|
$test变量保持了其值,也允许我们修改它的值,并在for循环之外跟其他变量一样使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
$ cat test1b
#!/bin/bash
# testing the or variable after the looping
for test in Alabama Alaska Arizona Arkansas California Colorado
do
echo "The next state is $test"
done
echo "The last state we visited was $test"
test=Connecticut
echo "Wait, now we're visiting $test"
$ ./test1b
The next state is Alabama
The next state is Alaska
The next state is Arizona
The next state is Arkansas
The next state is California
The next state is Colorado
The last state we visited was Colorado
Wait, now we're visiting Connecticut
|
shell看到了列表值中的单引号并尝试使用它们来定义一个单独的数据值,这真是把事情搞得一团糟。
1
2
3
4
5
6
7
8
9
10
11
12
|
$ cat badtest1
#!/bin/bash
# another example of how not to use the for command
for test in I don't konw if this'll work
do
echo "word:$test"
done
$ ./badtest1
word:I
word:dont know if thisll
word:work
|
有两种办法可以解决这个问题:使用转义字符(反斜线)来将单引号转义,使用双引号来定义用到单引号的值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ cat test2
#!/bin/bash
# another example of how not to use the for command
for test in I don\'t konw if "this'll" work
do
echo "word:$test"
done
$ ./test2
word:I
word:don't
word:konw
word:if
word:this'll
word:work
|
for循环假定每个值都是用空格分割的。如果有包含空格的数据值,就必须用双引号将这些值圈起来。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$ cat test3
#!/bin/bash
# an example of how to properly define values
for test in Nevada "New Hampshire" "New Mexico" "New York"
do
echo "Now going to $test"
done
$ ./test3
Now going to Nevada
Now going to New Hampshire
Now going to New Mexico
New goint to New York
|
有个特殊的环境变量IFS(internal field separator内部字段分隔符)。IFS环境变量定义了bash shell用作字段分割符的一系列字符。默认情况下,bash shell会将下列字段当做字段分割符:空格,制表符,换行符。(在for命令中会这样做)
用通配符读取目录中的所有文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$ cat test6
#!/bin/bash
# interate through all the files in a directory
for file in /home/rich/test/*
do
if [ -d "file" ] #在linux中,目录名和文件名中包含空格当然是合法的。要适应这种情况,应该将$file变量用双引号圈起来。如果不这么做,遇到含有空格的目录名或文件名时就会有错误产生。
then
echo "$file is a directory"
elif [ -f "$file" ]
then
echo "$file is a file"
fi
done
|
3.2 C语言风格的for命令
for (( variable assignment; condition; iteration process ))
注意,这种for命令,迭代器的算式没有使用expr命令,也没有使用$[operation]。
1
2
3
4
|
for (( i=1; i <= 10; i++))
do
echo "The next number is $i"
done
|
跳出外部循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$ cat test20
#!/bin/bash
# breaking out of an outer loop
for (( a = 1; a < 4; a++))
do
echo "Outer loop: $a"
for (( b = 1; b < 100; b++))
do
if [ $b -gt 4 ]
then
break 2 #跳出两层循环,跳出本循环直接break
fi
echo " Inner loop: $b"
done
done
|
continue的用法和break一样,只是它是直接进入下次循环的入口判断。
3.3 while命令
1
2
3
4
|
while test command
do
other command
done
|
示例
1
2
3
4
5
6
7
8
9
10
|
$ cat test10
#!/bin/bash
# while command test
var1=10
while [ $var1 -gt 0 ]
do
echo $var1
var1=$[ $var1 - 1 ]
done
|
3.4 until命令
1
2
3
4
|
until test commands
do
other commands
done
|
3.5 实例
列出PATH目录下所有的命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$ cat test25
#!/bin/bash
# finding files in the PATH
IPS=:
for folder in $PATH
do
echo "$folder:"
for file in $folder/*
do
if [ -x $file ]
then
echo " $file"
fi
done
done
|
创建多个用户账户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# read命令会自动读取.csv文本文件的下一行内容,所以不需要专门再写一个循环来处理。当read命令返回FLASE时(也就是读取完整个文件时),while命令就会退出。
$ cat test26
#!/bin/bash
# process new user accounts
input="users.csv"
while IFS=',' read -r userid name
do
echo "adding $userid"
useradd -c "$name" -m $userid
done < "$input"
$ cat users.csv
rich,Richard Blum
christine,Christine Bresnahan
barbara,Barbara Blum
tim,Timothy Bresnahan
|
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top
」,也可搜索「 后浪笔记一零二四 」找到我。
上一篇 «
下一篇 »