上篇,接下来是讲处理用户输入,显示数据和脚本控制,创建函数以及在脚本中添加颜色,至于后面的sed,正则表达式和awk有时间的话会单独写出来。另外,这本书还是挺不错的,讲的东西不是太简单,也不是太难,同时还有不少的例子可以给你消化。

处理用户输入

在shell脚本中,用$0表示程序名称,然后后面可以用$n表示第n个参数,如果n大于9的话需要用大括号把n括起来,比如${10}.不过$0中保存的是程序的完整路径,而不仅仅是程序的名称。如果只想要程序的名称的话,可以用basename命令,比如

name=</span>basename <span style="color: #d8bfd8;">$0</span><span style="color: #7fffd4;">

那么name中存的就是程序名称了,而不是完整的路径。

如果需要在脚本中使用参数的话,最好是先在使用之前对参数的个数进行检查,然后进行提示。

在shell中如果想使用最后一个参数的话,有两种方法,分别是

params=$#
echo The last parameter is $params
echo The last parameter is ${!#}

其中第二种不用能${$#},这样的话,会产生一个随机数。不过如果没有参数的话,上面两种还是不一样的,第一句会输出0,第二个会输出文件名。

接下来是$和$@表示所有的参数,但是$把所有的参数看成一个参数,$@把所有参数看成同一个字符串中的多个单词处理。允许对其中的值进行迭代。

还有就是shift移位操作,shift会把参数往左移一位,会用后面的覆盖前面的参数,而且不可恢复。

接下来讲的是getopt和getopts的应用,这是两个用来方便处理参数的命令。命令格式如下:

getopt options optstring parameters
getopts optstring variable

然后是读入命令read

read -t 5 -s -p “Please enter your name:” name

上面的命令表示5s有效(-t 5), 不回显,就像Linux的登录密码一样(-s),其实这里是把前景颜色和背景颜色设成了一样,提示字符串(-p “…”)。另外还有就是-n后面接数字num,表示读入num个字符之后自动结束,这个可以用在读入yes/no的地方,比如

read -n1 -p “Do you want to continue [Y/N]?” answer

则会在你输入了一个字符之后自动执行接下来的语句,不用你输入回车表示输入结束。

可以用cat filename | while read line来进行读取文件

接下来是显示数据的一章,包括各种文件重定向等。

首先我们Linux系统讲每个对象当成文件处理,使用文件描述符来标识文件对象,每个进程最多有9个打开文件的描述符,bash shell为特殊需要保留前3个文件描述服(0,1,2),0表示标准读入,1表示标准输出,2表示标准错误输出[一般也是输出在终端,和1输出的位置一起]。我们可以用重定向符号来把这些文件描述符进行重定向,比如下面的几句

cat < file 表示把标准读入重定向到file文件,即从file中读入
ls -l > test2 把标准输出重定向到test2,即输出到test2文件中
ls -l fjj fjkd 2> error 把错误信息写到error文件中

如果用>>则表示附加,即在原有的文件末尾追加,否则会覆盖现有文件

关于临时重定向和永久重定向。下面是例子

echo “This is an error” >2 #这事临时重定向
exec 1>textout #这事永久重定向,表示把输出重定向到文件textout中

在脚本中重定向还可以通过自己创建文件描述符来完成。自己创建的文件描述符还可以用来保存0,1,2这些系统文件描述符。如下面的例子

#!/bin/bash
exec 3>1 #文件描述符3重定向到标准输出
exec 1>test14out #标准输出重定向到test14out文件
echo “This should store in the output file”
echo “along with this line.”
exec 1>3 #文件描述符1重定向回标准输出
echo “Now things should be back to normal”

可以用”exec 3<> testfile”打开一个读写文件描述符 “exec 3>-“来关闭文件描述符3。可以用mktemp命令来创建临时文件和临时目录,”mktemp testing.XXXXXX”会创建一个临时文件,后面的X会被随机数所替代,当然可以加上-d选项来创建临时目录。

命令tee会把数据发给两个地方,一个是STDOUT,一个是后面接的文件名。比如”who | tee testfile”会把who的执行结果显示在STDOUT中和文件testfile中。

可以在脚本中捕获和移除信号,如下代码所示

#!/bin/bash

trap “echo byebye” EXIT #捕获EXIT信号 如果捕获到了就执行echo byebye

count=1
while [ $count -le 5 ]
do
echo “Loop #$count”
sleep 3
count=$[ $count + 1 ]
done

trap - EXIT #移除EXIT信号的捕获
echo “I just removed the trap”


另外书上还大致讲了jobs,nice,at,batch,cron命令的使用,这里就不对这些命令单独说了,

接下来是创建函数。创建函数的格式如下

function name {
commands
}
或者
name() {
commands
}

在函数中如果想返回一个数值的话,可以用return命令,不过返回的会被截取到[0,255]之间,而且要完成后尽快提取返回值。

#!/bin/bash
function db1 {
read -p “Enter a value: “ value
echo “doubling the value”
return $[ $value * 2 ]
}db1
echo “The new value is $?”

##下面是另外一种返回值的方式
function db1 {
read -p “Enter a value: “value
echo $[ $value * 2 ] #注意这里的写法
}
result = </span>db1<span style="color: #7fffd4;"> #这里是反引号
echo “The new value is $result”


上面的代码中给出了两种返回值的方式,这里可以自己进行选择。

传递参数和前面讲的参数的使用基本一致,这里就不罗嗦了。接下来就是变量的作用域了,一般来说bash里面的所有变量都是全局的,当然可以用local来限定,不然全部用全局变量的话,会对变量带来一定的麻烦。

下面的是给函数传函数和返回函数。

传数组可以用下面的方法
function testit {
local newarray
newarray=(</span><span style="color: #b0c4de; font-weight: bold;">echo</span> <span style="color: #d8bfd8;">$@</span><span style="color: #7fffd4;">)
echo “The new array value is: ${newarray[*]}”
}

myarray=(1 2 3 4 5)
echo “The original array is ${myarray[]}”
testit ${myarray[]}
下面的脚本会返回一个数组
function arraydblr {
local origarray
local newarray
local elements
local i
origarray=(</span><span style="color: #b0c4de; font-weight: bold;">echo</span> <span style="color: #7fffd4;">"$@"</span><span style="color: #7fffd4;">) #得到传过来的数组
newarray=(</span><span style="color: #b0c4de; font-weight: bold;">echo</span> <span style="color: #7fffd4;">"$@"</span><span style="color: #7fffd4;">)
elements=$[ $# - 1]
for ((i = 0; i<=$elements i++))
{
newarray[$i]=$[ ${origarray[$i]} 2]
}
echo ${newarray[
]} #返回一个数组
}
myarray=(1 2 3 4 5)
echo “The original array is: ${myarray[]}”
arg1=`echo ${myarray[]}</span> result(<span style="color: #7fffd4;">arraydblr $arg1`) #传一个数组给函数,并得到一个函数
echo “The new array is: ${result[*]}”
接下来是函数的递归,bash里面可以使用递归,使用的方式没有什么特别的,就和使用一般的函数一样。接下来可以创建函数库,然后通过”. funcname”来引入这个库,其中”.”表示source的意思。接下来就是可以在.bashrc里面创建函数或者导入自己的库函数,这样你就可以在任意的地方使用库函数里面的函数了。

至于在terminal创建窗口,可以用select命令,dialog命令,KDE下的kdialog和GNOME下的gdialog,zenity。这些的具体用法可以自行搜索。

到这里基本这本书除了sed,awk,脚本的介绍(zsh等)都讲完了,总体来说这本书还是挺不错的。有时间的话我会单独写sed和awk的一些用法。

Comments