Appearance
使用结构化命令
许多的程序要求对shell命令进行一些逻辑化的控制, 这些命令称为结构化命令
使用if-then命令
bash
if command
then
commands
fi
会运行if后面的哪那一个命令, 如果退出的状态码是0(运行成功), 就执行then
fi标志语句的结束
bash
if command; then
commands
fi
示例: 查找用户是否存在
bash
1 #!/bin/bash
2 testuser=jiao
3 if grep $testuser /etc/passwd
4 then
5 echo "This is my first command"
6 echo "second"
7 echo "Third"
8 ls -a /home/$testuser
9 fi
if-then-else语句
bash
if command
then
commends
else
commands
fi
bash
1 #!/bin/bash
2 testuser=NoSuchUser
3 if grep $testuser /etc/passwd
4 then
5 echo "The bash file for user $testuser are:"
6 ls -a /home/$testuser
7 echo
8 else
9 echo "The user $testuser does not exit on this system"
10 fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test4.sh
The user NoSuchUser does not exit on this system
嵌套if
bash
1 #!/bin/bash
2 testuser=NoSuchUser
3 if grep $testuser /etc/passwd
4 then
5 echo "The bash file for user $testuser are:"
6 ls -a /home/$testuser
7 echo
8 else
9 echo "The user $testuser does not exit on this system"
10 if ls -d /home/NoSuchUser
11 then echo "Hower $testuser has a directory"
12 fi
13 fi
bash
if command1
then
commands
elif command2
then
more commands
fi
bash
1 #!/bin/bash
2 testuser=NoSuchUsers
3 if grep $testuser /etc/passwd
4 then
5 echo "The bash file for user $testuser are:"
6 ls -a /home/$testuser
7 echo
8 elif ls -d /home/$testuser
9 echo "The user $testuser does not exit on this system"
10 then echo "Hower $testuser has a directory"
11 else
12 echo "The user $testuser dose not exit in this system"
13 echo "And don't have a dictory "
14 fi
test命令
if-then语句不能测试命令退出状态码之外的条件
test命令提供了在if-then语句中测试不同条件的途径。如果test命令中列出的条件成立,test命令就会退出并返回退出状态码0。这样if-then语句就与其他编程语言中的if-then语句以类似的方式工作了
bash
test condition
使用在if-then语句之中
bash
if test condition
then
commands
fi
如果不写test的condition就会以0退出
bash
1 #!/bin/bash
2 if test
3 then echo "No expression return a true"
4 else echo "return a False"
5 fi
6
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test7.sh
return a False
可以用来检测变量之中是不是有变量
bash
#!/bin/bash
my_variable="Full"
if test $my_variable
then
echo "The $my_variable expression returns a True"
else
echo "The $my_variable expression returns a False" fi
还有另一种测试的方法
bash
if [ condition ]
then
condition
fi
**注意:**第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错
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 |
- 数值变量可以使用在数值或变量之上
bash
1 #!/bin/bash
2 value1=10
3 value2=11
4 if [ $value1 -gt 5 ]
5 then echo "the test value $value1 is greater than 5"
6 fi
7 if [ $value1 -eq $value2 ]
8 then
9 echo "The value are equal"
10 else
11 echo "The value are different"
12 fi
bash
#!/bin/bash
# Using floating point numbers in test evaluations
value1=5.555
echo "The test value is $value1"
if [ $value1 -gt 5 ]
then
echo "The test value $value1 is greater than 5"
fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test9.sh
The test value is 5.555
./test9.sh: 第 8 行: [: 5.555:需要整数表达式
bash shell只能处理整数, 但是在$显示的时候没有问题, 在基于数字的函数中就不行了
字符串比较
比较 | 描述 |
---|---|
str1 = str2 | 检查str1是否和str2相同 |
str1 != str2 | 检查str1是否和str2不同 |
str1 < str2 | 检查str1是否比str2小 |
str1 > str2 | 检查str1是否比str2大 |
-n str1 | 检查str1的长度是否非0 |
-z str1 | 检查str1的长度是否为0 |
字符串相等
bash
1 #!/bin/bash
2 # 测试字符串是否相等
3 testuser=jiao
4 if [ $testuser = $USER ]
5 then
6 echo "Welcome $testuser"
7 fi
字符串顺序
- 大于号和小于号必须转义,否则shell会把它们当作重定向符号,把字符串值当作文件名;
- 大于和小于顺序和sort命令所采用的不同
bash
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ cat test11.sh
#!/bin/bash
val1=baseball
val2=honkey
if [ $val1 > $val2 ]
then echo "$val1 is greater than $val2"
else echo "$val1 is less than $val2"
fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test11.sh
baseball is greater than honkey
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ ls
honkey test10.sh test2.sh test4.sh test6.sh test8.sh test.py
test1 test11.sh test3.sh test5.sh test7.sh test9.sh
把大于号解释为输出重定向
要解决这个问题应该使用转义字符
bash
1 #!/bin/bash
2 val1=baseball
3 val2=honkey
4 if [ $val1 \> $val2 ]
5 then echo "$val1 is greater than $val2"
6 else echo "$val1 is less than $val2"
7 fi
排序的时候会认为是大写字母小于小写字母
比较测试中使用的是标准的ASCII顺序,根据每个字符的ASCII数值来决定排序结果。sort命令使用的是系统的本地化语言设置中定义的排序顺序。对于英语,本地化设置指定了在排序顺序中小写字母出现在大写字母前
字符串的大小
bash
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ cat test12.sh
#!/bin/bash
# 测试字符串的长度
val1=testing
val2=''
if [ -n $val1 ]
then echo "The string '$val1' is not empty"
else echo "The string '$val1' is empty"
fi
if [ -z $val2 ]
then echo "The string '$val2' is empty"
else echo "The string '$val2' is not empty"
fi
if [ -n $val3 ]
then echo "The string '$val3' is not empty"
else echo "The string '$val3' is empty"
fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test12.sh
The string 'testing' is not empty
The string '' is empty
The string '' is not empty
没有定义的变量会被认为是空的, 但是没有定义的或空的字符串会对脚本产生巨大的影响, 所以最好进行检查
文件比较
允许你测试文件目录的状态
比较 | 描述 |
---|---|
-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新 |
file1 -ot file2 | 检查file1是否比file2旧 |
检查目录
打算把文件写入某一个目录或者切换到某一个目录最好检查目录是否存在
bash
1 #!/bin/bash
2 jump_dictory=/home/jiao
3 if [ -d $jump_dictory ]
4 then
5 echo "This $jump_dictory exists"
6 cd $jump_dictory
7 ls
8 else
9 echo "This $jump_dictory dictory does not exit"
10 fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test13.sh
This /home/jiao exists
01_Python 公共的 模板 视频 图片 文档 下载 音乐 桌面 Makefile snap
检查对象是否存在
bash
if [ -e $location ]
then
...
检查文件
bash
if [ -f $location ]
then
...
检查是否可读
bash
1 #!/bin/bash
2 pwfile=/etc/shadow
3 if [ -f $pwfile ]
4 then
5 if [ -r $pwfile ]
6 then tail $pwfile
7 else echo "Sorry I am un able to read the $pwfile"
8 fi
9 else
10 echo "Sory the file $pwfile does'n exit"
11 fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test14.sh # 没有权限
Sorry I am un able to read the /etc/shadow
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ sudo ./test14.sh # 有权限
colord:*:18912:0:99999:7:::
geoclue:*:18912:0:99999:7:::
pulse:*:18912:0:99999:7:::
gnome-initial-setup:*:18912:0:99999:7:::
hplip:*:18912:0:99999:7:::
gdm:*:18912:0:99999:7:::
jiao:$6$apS9G8HD6duUAyqr$2e81915XsZW02XwXRuyWzo9GVElzwo3kr7X9JUDUlPMDdDCuiJT7mqbV1y6rc1C1EFcF1HeS6dt5dvFUv0Y0/1:19062:0:99999:7:::
systemd-coredump:!*:19063::::::
sshd:*:19064:0:99999:7:::
test:$6$57tVSKi5Obpm5cUj$cPcjBFM7iQtsLMOPMj8wsGvLpLGWEQDNDKnm.jDwOAE3RmiKbcIG7FqPF0924JUarmKU2yKy.L6BIwuG8Lrnt/:19207:0:99999:7:::
检查空文件
bash
1 #!/bin/bash
2 file_name=./test_file
3 if [ -f $file_name ]
4 then
5 if [ -s $file_name ]
6 then
7 echo "The file $file_name is existing and date in it"
8 echo "Will not remove it"
9 else
10 echo "The file $file_name is empty and will remove"
11 rm $file_name
12 fi
13 else
14 echo "the file dose not exit"
15 fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test15.sh # 没有创建的时候
the file dose not exit
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ touch test_file # 创建空文件
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test15.sh
The file ./test_file is empty and will remove
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ ls
honkey test10.sh test12.sh test14.sh test2.sh test4.sh test6.sh test8.sh test.py
test1 test11.sh test13.sh test15.sh test3.sh test5.sh test7.sh test9.sh
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ touch test_file #创建非空文件
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ vim test_file
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test15.sh
The file ./test_file is existing and date in it
Will not remove it
检查文件是否可写
bash
if [ -w $location ]
then
...
检查文件是否可执行
bash
if [ -x test16.sh ]
then
echo "You can run the script: "
./test16.sh
检查文件的所属关系
bash
if [ -O /etc/passwd ]
then
echo "You are the owner of the /etc/passwd file"
else
echo "Sorry, you are not the owner of the /etc/passwd file"
fi
比较文件所属的组
bash
#!/bin/bash
check file group test
if [ -G $HOME/testing ]
then
echo "You are in the same group as the file"
else
echo "The file is not owned by your group"
fi
只会比较用户的默认组, 不会比较其他的组
检查日期文件
在编写软件安装脚本的时候有用, 判断是不是新的版本
-nt比较会判定一个文件是否比另一个文件新。如果文件较新,那意味着它的文件创建日期更近。-ot比较会判定一个文件是否比另一个文件旧。如果文件较旧,意味着它的创建日期更早
bash
1 #!/bin/bash
2 if [ test2.sh -nt test5.sh ]
3 then echo "test2 is newer than test5"
4 else echo "test2 is older than test5"
5 fi
6 if [ test7.sh -ot test5.sh ]
7 then echo "test7 is older than test5"
8 else echo "test7 is nower than test5"
9 fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test16.sh
test2 is older than test5
test7 is nower than test5
复合条件测试
有两种bool运算
- [ condition1 ] && [ condition2 ]
- [ condition1 ] || [ condition2 ]
if-then的高级特性
使用双括号
除了test命令使用的标准数学运算符, 双括号允许使用更高级的运算
- ++
- --
- !
- ~
- **
- <<
- $>>$
- &
- |
- &&
- ||
可以在if语句中用双括号命令,也可以在脚本中的普通命令里使用来赋值
bash
1 #!/bin/bash
2 if ((1+1 ==2))
3 then echo "True"
4 else echo "False"
5 fi
使用双括号
可以使用针对字符串的高级操作, 比如和正则表达式进行比较
bash
1 #!/bin/bash
2 if [[ $USER == j* ]]
3 then echo "Hello $USER"
4 else echo "GUN"
5 fi
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test18.sh
Hello jiao
case命令
bash
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
将变量和不同的模式进行比较, 可以通过 | 分割出多个模式, *会匹配所有的值
bash
1 #!/bin/bash
2
3 case $USER in
4 jiao | dong)
5 echo "Welcome $USER"
6 echo "Enjoy your visit";;
7 testing)
8 echo "Do your test";;
9 *)
10 echo "Gun";;
11 esac
jiao@jiao-virtual-machine:~/桌面/linux-shell/12$ test19.sh
Welcome jiao
Enjoy your visit