从程序员的角度来看,Shell本身是一种用C语言编撰的程序,从用户的角度来看linux rename函数,Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行,又可以借助Shell脚本编程,完成愈加复杂的操作。在LinuxGUI日渐建立的明天,在系统管理等领域,Shell编程依然起着不可忽略的作用。深入地了解和熟练地把握Shell编程,是每一个Linux用户的选修功课之一。
Linux的Shell种类诸多,常见的有:
BourneShell(/usr/bin/sh或/bin/sh)、
BourneAgainShell(/bin/bash)、
CShell(/usr/bin/csh)、
KShell(/usr/bin/ksh)、
ShellforRoot(/sbin/sh)······
不同的Shell语言的句型有所不同,所以不能交换使用。每种Shell都有其特色之处,基本上,把握其中任何一种就足够了。在本文中,我们关注的重点是Bashlinux服务器搭建,也就是BourneAgainShell,因为易用和免费,Bash在日常工作中被广泛使用;同时,Bash也是大多数Linux系统默认的Shell。在通常情况下,人们并不分辨BourneShell和BourneAgainShell,所以,在下边的文字中,我们可以见到#!/bin/sh,它同样也可以改为#!/bin/bash。
借助vi等文本编辑器编撰Shell脚本的格式是固定的,如下:
#!/bin/sh
#comments
Yourcommandsgohere
首行中的符号#!告诉系统其后路径所指定的程序即是解释此脚本文件的Shell程序。假如首行没有这句话,在执行脚本文件的时侯,将会出现错误。后续的部份就是主程序,Shell脚本像中级语言一样,也有变量形参,也有控制句子。除第一行外,以#开头的行就是注释行,直至此行的结束。假如一行未完成linux rename函数,可以在行尾加上",这个符号表明下一行与此行会合并为同一行。
编辑完毕,将脚本读档为filename.sh,文件名后缀sh表明这是一个Bash脚本文件。执行脚本的时侯,要先将脚本文件的属性改为可执行的:
chmod+xfilename.sh
执行脚本的方式是:
./filename.sh
下边我们从精典的“helloworld”入手,看一看最简单的Shell脚本的模样。
#!/bin/sh
#printhelloworldintheconsolewindow
a="helloworld"
echo$a
ShellScript是一种弱类型语言,使用变量的时侯无需首先申明其类型。新的变量会在本地数据区分配显存进行储存,这个变量归当前的Shell所有,任何子进程都不能访问本地变量。这种变量与环境变量不同,环境变量被储存在另一显存区,称作用户环境区,这块显存中的变量可以被单进程访问。
变量形参的方法是:
variable_name=variable_value
假如对一个早已有值的变量形参linux 版本,新值将代替旧值。取值的时侯要在变量名前加$,$variable_name可以在冒号中使用,这一点和其他中级语言是显著不同的。
倘若出现混淆的情况,可以使用花括弧来分辨,比如:echo"Hi,$as"就不会输出“Hi,helloworlds”,而是输出“Hi,”。这是由于Shell把$as当作一个变量,而$as未被形参,其值为空。正确的方式是:echo"Hi,${a}s"单冒号中的变量不会进行变量替换操作。
关于变量,还须要晓得几个与其相关的Linux命令。
env用于显示用户环境区中的变量及其取值;set用于显示本地数据区和用户环境区中的变量及其取值;unset用于删掉指定变量当前的取值,该值将被指定为NULL;export命令用于将本地数据区中的变量转移到用户环境区。
下边我们来看一个更复杂的反例,结合这个反例,我们来述说ShellScript的句型。
#!/bin/bash
if [ $# -lt 3 ]; then
cat<<help
ren -- renames a number of files using sed regular expressions
USAGE: ren 'regexp' 'replacement' files
EXAMPLE: rename all *.HTM files in *.html:
ren 'HTM$' 'html' *.HTM
HELP
exit 0
fi
OLD="$1"
NEW="$2"
# The shift command removes one argument from the list of
shift
shift
# $* contains now all the files:
for file in $*; do
if [ -f "$file" ]; then
newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
if [ -f "$newfile" ]; then
echo "ERROR: $newfile exists already"
else
echo "renaming $file to $newfile "
mv "$file" "$newfile"
fi
fi
done
我们从头来看,上面两行上一个反例中早已解释过了,从第三行开始,有新的内容。if句子和其他编程语言相像,都是流程控制句子。它的句型是:
if …; then
…
elif …; then
…
else
…
fi
与其他语言不同,ShellScript中if句子的条件部份要以分号来分隔。第三行中的[]表示条件测试,常用的条件测试有下边几种:
[-f"$file"]判定$file是否是一个文件
[$a-lt3]判定$a的值是否大于3,同样-gt和-le分别表示小于或大于等于
[-x"$file"]判定$file是否存在且有可执行权限,同样-r测试文件可读性
[-n"$a"]判定变量$a是否有值,测试空串用-z
["$a"="$b"]判定$a和$b的取值是否相等
[cond1-acond2]判定cond1和cond2是否同时创立,-o表示cond1和cond2有一创立
要注意条件测试部份中的空格。在方括弧的右侧都有空格,在-f、-lt、=等符号两边同样也有空格。若果没有那些空格,Shell解释脚本的时侯才会出错。
$#表示包括$0在内的命令行参数的个数。在Shell中,脚本名称本身是$0,剩下的依次是$0、$1、$2…、${10}、${11},等等。$*表示整个参数列表,不包括$0,也就是说不包括文件名的参数列表。
如今我们明白第三行的涵义是假如脚本文件的参数多于三个,则执行if和fi句子之间的内容。之后,从第四行到第十一行之间的内容在ShellScript编程中被称为Here文档,Here文档用于将多行文本传递给某一命令。Here文档的格式是以