从今天开始,进入shell脚本编程大门,开启shell征途。
shell中的基本概念
1.环境变量IFS
IFS(Internal Field Seprator ) ,内部域分隔符,主要用来对文本的默认分隔符进行设置,默认情况下,对于一个文本,分隔符是space,tab,newline,也就是空格,Tab,换行。但是我们可以通过自己的修改来设置新的分隔符。
测试代码test00:
#!/bin/bash
#没有更改IFS值
var2="1 2 3 4 5 6"
for var1 in $var2
do
echo "$var1"
done
测试结果:
更改IFS值后:
#!/bin/bash
#更改IFS
#test00
IFS_OLD=$IFS #将原来的IFS保存为IFS_OLD
IFS='\n' #设置新的IFS值为:换行符
var2="1 2 3 4 5 6"
for var1 in $var2
do
echo "$var1"
done
输出结果为:
再次看看添加'-'后的结果(修改后的代码):
#!/bin/bash
#更改IFS
#test00
IFS_OLD=$IFS #将原来的IFS保存为IFS_OLD
IFS='-' #设置新的IFS值为:换行符
var2="1- 2 -3 - 4-5- 6" #注意间隔
for var1 in $var2
do
echo "$var1"
done
输出结果:
2.循环控制语句
在shell中,for循环遵循了C语言的语法,而基本循环语句和C语言也没什么不同,只是加了do
,done
,if-elif-else语句也只是添加了一个test command
(中括号),也同样有break, continue语句,但是break语句中,默认的break
是跳出内循环,(break 1
);当要跳出上一层循环时,用break 2
即可。
测试代码:
#!/bin/bash
#break out of an inner loop
#test20
for ((a =1; a < 4; a++))
do
echo "Outer loop: $a"
for ((b=1; b<100; b++))
do
if [ $b -eq 5 ] # test command
then
break
fi #if 语句的结束标志
echo " Inner loop: $b"
done #循环语句结束标志
done
输出结果:
跳出外部循环:(修改test20)
#!/bin/bash
#break out of an inner loop
for ((a =1; a < 4; a++))
do
echo "Outer loop: $a"
for ((b=1; b<100; b++))
do
if [ $b -eq 5 ] # test command
then
break 2 #注意!!!!!!!
fi
echo " Inner loop: $b"
done
done
输出结果为:
until循环
注:在until,while循环中,都可以用多条test命令
#!/bin/bash
#until 多条test命令循环
var1=100
until echo $var1
[ $var1 -eq 0 ] #第二条test命令(当命令返回0状态码时停止循环)
do
echo Inside the loop: $var1
var1=$[$var1-25]
done
输出结果为:
上面提到了当test命令返回0状态码时结束循环,那么现在就来看看什么是命令的状态返回码。
退出状态代码
|代码|描述| |代码|描述|
|:-----|:---||----------:|-------:|
|0|命令成功完成||128|无效的退出参数|
|1|通常的未知错误||128+x|使用Linux信号x的致命错误|
|2|误用shell命令||130|使用CTRL-C终止的命令|
|126|命令无法执行||255|规范外的退出状态|
|127|没有找到命令|||
shell命令处理完毕后,都有一个退出状态,这个退出状态是一个介于0-255之间的整数值,当命令执行完毕后,命令就会把退出状态传递给shell,我们现在来检测它。鉴于Linux提供$?特殊变量来保存最后一条命令执行结束的退出状态,我们就用$?来核对退出状态。
1.命令成功执行完毕的状态码应为0:
2.没有此命令:127:
3.退出状态为126表示用户没有权限执行这条命令:
4.常见的未知错误:
5.shell默认返回最后一条命令执行后的退出状态码,但我们可以自己设置返回状态码,用exit语句,不过要小心,因为状态码范围是0-255:
#!/bin/bash
#自己设置返回码
var1=10
var2=30
var3=$[$var1+$var2]
echo 结果是 $var3
exit 5 #自己设置的退出状态码(相当于高级语言里的return)
回顾上面的until语句,当test语句返回值是0,表示test条件符合,就退出循环。
3.处理循环输出
可以在shell脚本中使用管道或者重定向循环输出结果。可以在done命令的末尾添加命令来做到这一点:
#!/bin/bash
for ((a=1; a<10; a++))
do
echo "The number is $a"
done > test.txt #输出重定向
echo "The command is finished."
运行结果:
4.总结下test命令:条件判断命令
- 数值比较:
命令格式 | 描述 | 比较 | 描述 | |
---|---|---|---|---|
n1 -eq n2 | n1是否等于n2 | n1 -le n2 | n1是否小于等于n2 | |
n1 -ge n2 | n1 是否大于等于n2 | n1 -lt n2 | n1是否小于n2 | |
n1 -gt n2 | n1是否大于n2 | n1 -ne n2 | n1是否不等于n2 |
2.字符串比较
|比较|描述||比较|描述|
|:---|:----||------:|------:|
|str1 = str2|检查str1是否与str2相同||str1 > str2|检查str1是否大于str2|
|str1 != str2 |检查str1是否不等于str2||-n str1|检查str1长度是否大于0|
|str1 < str2 |检查str1是否小于str2||-z str1|检查str1长度是否为0|
3.文件比较
|比较|描述||比较|描述|
|:------|:----||-------:|-----------:|
|-d file|file是否存在且是目录||-e 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旧|
注意:文件的新旧指的是文件的创建时间。(越是早创建,越是旧)