1.构建基本脚本(第十一章)
1.简单脚本与显示消息
例1
#!/bin/bash #格式规定的第一句话,这行代码的!后表明了脚本要用Bash shell执行#分开写两行代码,脚本会一次执行date #显示当前时间who #显示登陆账户
- 刚写好的脚本不能直接运行,需要赋予执行权限
chmod u+x test.sh #赋予脚本执行权限
- 赋予权限后,在命令行输入:
./test.sh # ./的意思是当前目录
例2
#!/bin/bash #echo "文本" 则文本会在命令行中显示,注意使用双引号可以避免很多麻烦echo -n "当前时间:" #使用 -n 命令可以使date的结果和当前时间处在同一行date echo " 在线用户" # 普通的echo ,在线用户自己独占一行 who
2.使用变量
-
在脚本中出现$,就意味着这是个变量,如$val1,反过来要表示美元的话要加上转义符号 $15 即为15美元
-
用户可以自己定义变量,但有两点注意:
- 区分大小写 2. 变量、符号、值之间不能有空格,特别注意
-
用户变量可以通过美元符号引用
var1=10 #不能有空格var2=$var1 #用$符号引用
- 利用$()可以从命令的输出中提取信息,并将其赋值给变量:
testing=$(date) #时间信息赋值给了testing
#常见用法,将日期加入文件名#!/bin/bashtoday=$(date +%y%m%d) #提取时间信息中的年(y)月(m)日(d)mv test* test*.$today
3.重定向输入与输出以及管道
- 输出重定向(大于号>):将命令输出发送到某个文件:
date > text #将日期信息保存在text文件中
- 若不想覆盖文件则使用远大于号>>,
date>>text #将日期【添加】到text文件中
- 输入重定向(小于号<):将文件中的信息输入到命令中
- 使用内联重定向(远小于号<<)需要指定结束字符,常用EOF
var5=$(bc << EOF #bc,shell的计算器,这段代码计算了var1*var2+var3+var4的值,并取四位小数scale = 4a1 = ( $var1 * $var2 )b1 = ($var3 * $var4 )a1+b1EOF)
- 管道,命令1的输出作为命令2的输入。二者同时进行
apt -list | sort >apt.list #将apt包的列表排序并输出到apt.list文件中
4.数学运算
- 贼麻烦、注意空格
- expr命令可以进行整数计算(不推荐)
·expr 1 + 5 #空格不能省略
expr 1 * 5 #会报错expr 1 \* 5 #加上转义符后,正确
- 使用方括号执行运算会简单很多
#以下两行代码是一个意思[ 4 *1 ]expr 4 \* 1
- 要支持小数点必须使用 bc
#利用管道将echo命令的结果输入到计算器bc中,返回结果var1=$(echo "scale=4;3.14 / 5" | bc) #scale可以确定小数位数但不是四舍五入而是去尾,切记
5.退出码
echo $? #查看上一个命令的退出码
- 退出码与错误有关,正常结束的为0,也可以设定退出码,脚本中加入
exit 5
退出码即为5 - 强制终止 CTRL+C
2.if-then 选择结构(第十二章)
1.基本代码 if -then -else
例1:
#!/bin/bash#if用法的基本举例if pwd #if + 命令 若命令执行(退出码为0,或者说既判为真?),则进行thenthen echo " It worked" #输出 It worked,至于pwd的输出,不会显示出来的fi #if 语句结束#另一个例子if wrong #if + 命令 若命令不执行(退出码不为0,或者说既判为否?),则跳过thenthen echo " It worked" #输出 It worked,至于pwd的输出,不会显示出来的fi #if 语句结束
例2
#!/bin/bash# if -then -else 命令执行则then,不执行则elsetestuser=NoSuchUser#if grep $testuser /etc/passwdthen echo "The bash files for user $testuser are:" ls - /home/$testuser/.b* echo #输出空一行else echo "The user $testuser does not exist on the system" echofi
例3
#!/bin/bash#嵌套的高级用法 elif ,其实是:else+iftestuser=NoSuchUser#if grep $testuser /etc/passwdthen echo "The user $testuser exists on the system"elif ls -d /home/$testuser #else后面接if,连写的话会很方便then echo "The user $testuser does not exist on the system" echo "However ,$testuser has a directory"fi
2.test命令(比较、判断)
- if-then语句只能判断退出码。但利用test语句,可以判断真假
- test语句可以用方括号 [ ] 简写,和计算一样,注意方括号前后要有空格
- test可以进行数值比较,但只能比较整数
#数值比较功能#eq 为= g为greater l大概为less[ n1 -eq n2 ] #n1=n2[ n1 -ge n2 ] #n1>=n2[ n1 -gt n2 ] #n1>n2[ n1 -le n2 ] #n1<=n2[ n1 -lt n2 ] #n1
- test可以进行字符串比较
#字符串比较功能#使用大于小于号一定要注意加上转义号,否则会生成文件并判定为真[ str1 = str2 ] #比较字符串是否相同[ str1 !=s tr2 ] #比较字符串是否不同[ str1 \< str2 ] #字符串1是否比2小,注意转义号[ str1 \> str2 ] #字符串1是否比2大,注意转义号[ -n str1 ] #字符串长度是否为非0[ -z str1 ] #字符串长度是否为0#test的比较大小和sort的正好反过来,因为test用的是标准ASCII顺序
- test 可以进行文件比较(最常用的)
#可以用来检查系统中的文件,贼好用[ -d file ] #检查file是否存在并为一个目录(dir)[ -e file ] #检查file是否存(exist)[ -f file ] #检查file是否存在并为一个文件(file)[ -r file ] #检查file是否存在并可读(read)[ -s file ] #检查file是否存在并非空[ -w file ] #检查file是否存在并可写(write)[ -x file ] #检查file是否存在并可执行[ file1 -nt file2 ] #检查file1是否比file2新(newer then)[ file1 -ot file2 ] #检查file1是否比file2旧(older then)
- 使用双括号可以处理数学表达式,还不懂,不展开
- 使用双方括号可以处理字符串,还不懂,不展开
3.case命令
- 使用case可以不停的检查_同一个_变量
#!/bin/bash#检查用户,对应的用户有不同的输出case $USER in #注意inrich | barbara) #注意) echo "Welcome, $USER" echo "Please enjoy your visit";; #注意双分号testing) echo "Special testing account";; #注意双分号Jessica) echo "Do not forget to log off when you're done";; #注意双分号*) echo Sorry, you are not allowed here";; #注意双分号esac #反写,结束
3.for、while、untill 循环结构(第十三章)
####1.for 命令
- 使用for命令,可以使用列表(或变量)中的值
#!/bin/bash#for test in "Beijing Nanjing Shanghai Guangzhou Jinan Xi'an" #把列表中的值依次赋值给test,又用到了in,另外双引号是个好东西do echo "The next city is $test"done # 结束符号
- 使用for命令,可以使用文件中的值
#!/bin/bash#file="cities" #cities 文件名。文件需要和脚本在同一目录下#for test in $( cat $file) #读取文件中的值do echo "The next city is $test"done #但有时,文件中有空格,如New Shanghai,输出就会当成New 和 Shanghai两个,因为的字段分隔符为空格
- 字段分隔符 IFS。默认的字段分隔符为:1.空格 2.制表符 3.换行符
- IFS 是可以在脚本中改变的
IFS=$'\n' #以换行符为字段分隔符IFS=$'\n':;" #以换行符、冒号、分号、双引号为字段分隔符##如果需要多次改变IFS,把默认的先存起来是个安全的好主意IFS.OLD=$IFS
- 可以使用通配符如*来遍历目录
- C语言风格的for命令是处理计数的神器,真好用
#!/bin/bash#注意双括号和分号for (( i=1; i <=10 ;i++ )) #从1开始,每次加1,到10停止do echo "The nest number is $i"done##还可以使用多个变量哦,用逗号分隔for (( a=1 , b=10; a <=10 ;a++ ,b-- )) do echo " $a - $b" #没做计算,就是输出done
2.while 循环
- 当test到否,while就停止循环
#!/bin/bash#var1=10#while [ $var1 -gt 0 ] #若var1大于0则继续do echo $var1 var1=$[ $var1 -1 ] #计算减一,注意方括号前后的空格done
- while允许使用多个test命令(或者其他命令),所有的test都会执行,哪怕那一次有个test没有通过
3.unit 循环
- 当test到until就停止循环
#!/bin/bash#var1=100#until [ $var1 -eq 0 ]do echo $var1 var1=$[ var1 -25 ]done
- 与while的区别是同样到0结束,while的最后输出有0,until则不包括0
4.其他
- 循环可以嵌套,好好使用修改IFS的技术
- 用break可以退出循环,
break
是退出当下循环,break 2
是退出外面一层的循环,break 3
是退出外面的外面一层的循环 - 利用continue可以跳过某些循环
#!/bin/bash#这个脚本最后的输出会跳过var1大于5小于10的部分for ((var1 =1 ; var1<15 ;var1++ ))do if [ $var1 -gt 5 ] && [ $var -lt 10 ] then continue fi echo "The number is $var1"done#注意,continue不要和计数部分写在一起,会跳过计数造成死循环的
- 循环的输出,可以在done后面进行处理:
done | sort >test.txt
将循环输出排序并保存在test.txt文件中
5.一个小例子
#!/bin/bash#这个脚本在扫描PATH环境变量下所有有可执行文件的目录,也就是电脑中所有安装的程序#输出真多……IFS=:for folder in $PATHdo echo "$folder:" for file in $folder/* do if [ -x $file ] then echo " $file" fi donedone
- 讲真,多练习才是真的……过书时练习写的代码在 需要的自取。另注意路径……
未完待续,有新想法再写