第一章:The Missing Code Library--12.建立一个Shell脚本库
第一章中的很多脚本是用函数的形式写的,而不是独立脚本,这样做的目的就是可以在别的脚本中使用它们而不用进行系统调用。shell脚本中并没有像C一样的#include特性,不过它有一个很重要的能力叫做souring a file,有同样的效果。想搞明白这个为什么重要,那么我们来思考下。如果你在shell中调用一个shell脚本,默认情况下调用的脚本是在自己的子shell中运行。你可以马上通过测试证明这点:
cat tinyscript.sh # 脚本中只有一行 test=2 test=2 # 打屏 test=1 # 现在键入这行 tinyscript.sh # 再键入 echo $test # 再键入 1 # 打屏
由于这个脚本改变了运行脚本的子shell中变量test的值,所以在当前的shell环境中的当前存在的变量test的值,并没有被影响到。如果你使用source运算符来运行脚本,它就会像是脚本中的每个命令直接被输入在当前shell中一样被执行:
1 source tinyscript.sh # 接着上面的继续键入 2 echo $test # 键入 3 2 # 打屏
注:原书上不是用的source,用的是点号“.”,经过测试,老七的终端不支持。
如你所想,如果你在一个source进来的脚本中有条exit 0的命令,它就会退出shell,然后登出窗口。(也就是整个都退出了)
代码:
为了把本章中的函数放到一个库中以便于在别的脚本中使用,把它们提取出来,然后放到一个大的文件中。如果这个大文件叫做library.sh, 那么用来访问所有的函数的一个测试脚本看起来就如下所述:
1 #!/bin/sh 2 3 # library.sh 测试脚本 4 5 source library.sh 6 7 echon "First off, do you have echo in your path?(1=yes, 2=no): " 8 read answer 9 while ! validint $answer 1 2; do 10 echon "Try again.Do you have echo" 11 echon "in your path?(1=yes, 2=no): " 12 read answer 13 done 14 15 if ! checkForCmdInPath "echo"; then 16 echo "Nope, can't find the echo command." 17 else 18 echo "The echo command is in PATH." 19 fi 20 21 echo "" 22 echon "Enter a year you think might be a leap year: " 23 read year 24 25 while ! validint $year 1 9999; do 26 echon "Please enter a year in the correct format: " 27 read year 28 done 29 30 if isLeapYear $year; then 31 echo "You're right! $year was a leap year." 32 else 33 echo "Nope, that's not a leap year." 34 fi 35 36 exit 0
注意,library.sh是一个混合文件,在使用了source library.sh后,所有的函数都被读入和包含了到了这个脚本中的运行时环境中这是一个很有用处的方法,只要有需要,就可以一次次的利用它。
运行脚本:
简单的在命令行调用就行了。
运行结果:
1 ./testLibrary.sh 2 First off, do you have echo in your path?(1=yes, 2=no): 4 3 输入的值太大:输入的上限是 2 4 Try again.Do you have echoin your path?(1=yes, 2=no): 1 5 The echo command is in PATH. 6 7 Enter a year you think might be a leap year: 2111111 8 输入的值太大:输入的上限是 9999 9 Please enter a year in the correct format: 21.4 10 错误的数字格式!只有数字,不能有逗号、空格等 11 Please enter a year in the correct format: 432 12 You're right! 432 was a leap year.
注:说白了,就是把之前我们写的脚本中的函数,放到Library.sh中,然后用命令source导入。