充值中心网站怎么做,佛山百度关键词推广,jsp借书网站开发,企业做网站需要租服务器吗我们可以使用任意一种文字编辑器#xff0c;比如gedit、kedit、emacs、vi等来编写shell脚本#xff0c;它必须以如下行开始#xff08;必须放在文件的第一行#xff09;#xff1a; # !/bin/sh
...注意#xff1a;最好使用“!/bin/bash”而不是“!/bin/sh”#xff0c;…我们可以使用任意一种文字编辑器比如gedit、kedit、emacs、vi等来编写shell脚本它必须以如下行开始必须放在文件的第一行 # !/bin/sh
...注意最好使用“!/bin/bash”而不是“!/bin/sh”如果使用tc shell改为tcsh其他类似。 符号#!用来告诉系统执行该脚本的程序本例使用/bin/sh。编辑结束并保存后如果要执行该脚本必须先使其可执行 chmod x filename 此后在该脚本所在目录下输入 ./filename 即可执行该脚本。 变量赋值和引用 Shell编程中使用变量无需事先声明同时变量名的命名须遵循如下规则 首个字符必须为字母a-zA-Z 中间不能有空格可以使用下划线_ 不能使用标点符号 不能使用bash里的关键字可用help命令查看保留关键字 需要给变量赋值时可以这么写 变量名值 要取用一个变量的值只需在变量名前面加一个$ ( 注意: 给变量赋值的时候不能在两边留空格 ) #!/bin/sh
# 对变量赋值
ahello world #等号两边均不能有空格存在
# 打印变量a的值
echo A is: $a 挑个自己喜欢的编辑器输入上述内容并保存为文件first然后执行 chmod x first 使其可执行最后输入 ./first 执行该脚本。其输出结果如下 A is: hello world 有时候变量名可能会和其它文字混淆比如 num2
echo this is the $numnd 上述脚本并不会输出this is the 2nd而是this is the 这是由于shell会去搜索变量numnd的值而实际上这个变量此时并没有值。这时我们可以用花括号来告诉shell要打印的是num变量 num2
echo this is the ${num}nd 其输出结果为this is the 2nd 需要注意shell的默认赋值是字符串赋值。比如 var1
var$var1
echo $var打印出来的不是2而是11。为了达到我们想要的效果有以下几种表达方式 let var1
var$[$var1]
varexpr $var 1#注意加号两边的空格否则还是按照字符串的方式赋值。注意前两种方式在bash下有效在sh下会出错。 let表示数学运算expr用于整数值运算每一项用空格隔开$[]将中括号内的表达式作为数学运算先计算结果再输出。 Shell脚本中有许多变量是系统自动设定的我们将在用到这些变量时再作说明。除了只在脚本内有效的普通shell变量外还有环境变量即那些由export关键字处理过的变量。本文不讨论环境变量因为它们一般只在登录脚本中用到。 Shell里的流程控制 if 语 句 if表达式如果条件为真则执行then后的部分: if ....; then....
elif ....; then....
else....
fi大多数情况下可以使用测试命令来对条件进行测试比如可以比较字符串、判断文件是否存在及是否可读等等……通常用 [ ] 来表示条件测试注意这里的空格很重要要确保方括号前后的空格。 [ -f somefile ] 判断是否是一个文件 [ -x /bin/ls ] 判断/bin/ls是否存在并有可执行权限 [ -n $var ] 判断$var变量是否有值 [ $a $b ] 判断$a和$b是否相等 执行man test可以查看所有测试表达式可以比较和判断的类型。下面是一个简单的if语句 #!/bin/shif [ ${SHELL} /bin/bash ]; thenecho your login shell is the bash (bourne again shell)
elseecho your login shell is not bash but ${SHELL}
fi变量$SHELL包含有登录shell的名称我们拿它和/bin/bash进行比较以判断当前使用的shell是否为bash。 和 || 操作符 熟悉C语言的朋友可能会喜欢下面的表达式 [ -f /etc/shadow ] echo This computer uses shadow passwords这里的 就是一个快捷操作符如果左边的表达式为真则执行右边的语句你也可以把它看作逻辑运算里的与操作。上述脚本表示如果/etc/shadow文件存在则打印”This computer uses shadow passwords”。同样shell编程中还可以用或操作(||)例如 #!/bin/shmailfolder/var/spool/mail/james
[ -r $mailfolder ] || { echo Can not read $mailfolder ; exit 1; }
echo $mailfolder has mail from:
grep ^From $mailfolder该脚本首先判断mailfolder是否可读如果可读则打印该文件中的From 一行。如果不可读则或操作生效打印错误信息后脚本退出。需要注意的是这里我们必须使用如下两个命令 -打印错误信息 -退出程序 我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用普通函数稍后再作说明。即使不用与和或操作符我们也可以用if表达式完成任何事情但是使用与或操作符会更便利很多 。 case 语句 case表达式可以用来匹配一个给定的字符串而不是数字可别和C语言里的switch...case混淆。 case ... in...) do something here
esacfile命令可以辨别出一个给定文件的文件类型如file lf.gz其输出结果为 lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix我们利用这点写了一个名为smartzip的脚本该脚本可以自动解压bzip2, gzip和zip 类型的压缩文件 #!/bin/shftypefile $1 # Note and is differentcase $ftype in$1: Zip archive*)unzip $1 ;;$1: gzip compressed*)gunzip $1 ;;$1: bzip2 compressed*)bunzip2 $1 ;;*) echo File $1 can not be uncompressed with smartzip;;esac你可能注意到上面使用了一个特殊变量$1该变量包含有传递给该脚本的第一个参数值。也就是说当我们运行 smartzip articles.zip$1 就是字符串 articles.zip。 select 语句 select表达式是bash的一种扩展应用擅长于交互式场合。用户可以从一组不同的值中进行选择 select var in ... ; dobreak;
done
.... now $var can be used .... 下面是一个简单的示例 #!/bin/shecho What is your favourite OS?
select var in Linux Gnu Hurd Free BSD Other; dobreak;
done
echo You have selected $var如果 以上脚本运行出现 select NOT FOUND 将 #!/bin/sh 改为 #!/bin/bash 该脚本的运行结果如下 What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You have selected Linuxwhile/for 循环 在shell中可以使用如下循环 while ...; do....
done只要测试表达式条件为真则while循环将一直运行。关键字break用来跳出循环而关键字”continue”则可以跳过一个循环的余下部分直接跳到下一次循环中。 for循环会查看一个字符串行表字符串用空格分隔并将其赋给一个变量 for var in ....; do....
done下面的示例会把A B C分别打印到屏幕上 #!/bin/shfor var in A B C ; doecho var is $var
done下面是一个实用的脚本showrpm其功能是打印一些RPM包的统计信息 #!/bin/sh# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 ...
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in $*; doif [ -r $rpmpackage ];thenecho $rpmpackage rpm -qi -p $rpmpackageelseecho ERROR: cannot read file $rpmpackagefi
done这里出现了第二个特殊变量$*该变量包含有输入的所有命令行参数值。如果你运行showrpm openssh.rpm w3m.rpm webgrep.rpm那么 $* 就包含有 3 个字符串即openssh.rpm, w3m.rpm和 webgrep.rpm。 Shell里的一些特殊符号 引号 在向程序传递任何参数之前程序会扩展通配符和变量。这里所谓的扩展是指程序会把通配符比如*替换成适当的文件名把变量替换成变量值。我们可以使用引号来防止这种扩展先来看一个例子假设在当前目录下有两个jpg文件mail.jpg和tux.jpg。 #!/bin/shecho *.jpg运行结果为 mail.jpg tux.jpg引号单引号和双引号可以防止通配符*的扩展 #!/bin/shecho *.jpg
echo *.jpg其运行结果为 *.jpg
*.jpg其中单引号更严格一些它可以防止任何变量扩展而双引号可以防止通配符扩展但允许变量扩展 #!/bin/shecho $SHELL
echo $SHELL
echo $SHELL运行结果为 /bin/bash
/bin/bash
$SHELL此外还有一种防止这种扩展的方法即使用转义字符——反斜杆:/ echo /*.jpg
echo /$SHELL输出结果为 *.jpg
$SHELLHere Document 当要将几行文字传递给一个命令时用here documents是一种不错的方法。对每个脚本写一段帮助性的文字是很有用的此时如果使用here documents就不必用echo函数一行行输出。Here document以 开头后面接上一个字符串这个字符串还必须出现在here document的末尾。下面是一个例子在该例子中我们对多个文件进行重命名并且使用here documents打印帮助 #!/bin/sh# we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
cat HELPren -- renames a number of files using sed regular expressions USAGE: ren regexp replacement files...EXAMPLE: rename all *.HTM files in *.html:ren HTM$ html *.HTMHELPexit 0
fi
OLD$1
NEW$2
# The shift command removes one argument from the list of
# command line arguments.
shift
shift
# $* contains now all the files:
for file in $*; doif [ -f $file ] ; thennewfileecho $file | sed s/${OLD}/${NEW}/gif [ -f $newfile ]; thenecho ERROR: $newfile exists alreadyelseecho renaming $file to $newfile ...mv $file $newfilefifi
done这个示例有点复杂我们需要多花点时间来说明一番。第一个if表达式判断输入命令行参数是否小于3个 (特殊变量$# 表示包含参数的个数) 。如果输入参数小于3个则将帮助文字传递给cat命令然后由cat命令将其打印在屏幕上。打印帮助文字后程序退出。如果输入参数等于或大于3个我们就将第一个参数赋值给变量OLD第二个参数赋值给变量NEW。下一步我们使用shift命令将第一个和第二个参数从参数列表中删除这样原来的第三个参数就成为参数列表$*的第一个参数。然后我们开始循环命令行参数列表被一个接一个地被赋值给变量$file。接着我们判断该文件是否存在如果存在则通过sed命令搜索和替换来产生新的文件名。然后将反短斜线内命令结果赋值给newfile。这样我们就达到了目的得到了旧文件名和新文件名。然后使用 mv命令进行重命名 Shell里的函数 如果你写过比较复杂的脚本就会发现可能在几个地方使用了相同的代码这时如果用上函数会方便很多。函数的大致样子如下 functionname()
{
# inside the body $1 is the first argument given to the function
# $2 the second ...
body
} 你需要在每个脚本的开始对函数进行声明。 下面是一个名为xtitlebar的脚本它可以改变终端窗口的名称。这里使用了一个名为help的函数该函数在脚本中使用了两次 #!/bin/sh
# vim: set sw4 ts4 et:
help()
{
cat HELP
xtitlebar -- change the name of an xterm, gnome-terminal or kde konsole
USAGE: xtitlebar [-h] string_for_titelbar
OPTIONS: -h help text
EXAMPLE: xtitlebar cvs
HELP
exit 0
}
# in case of error or if -h is given we call the function help:
[ -z $1 ] help
[ $1 -h ] help
# send the escape sequence to change the xterm titelbar:
echo -e 33]0;$107
# 在脚本中提供帮助是一种很好的编程习惯可以方便其他用户和自己使用和理解脚本。 命令行参数 XXXXXXXXXXXXXXXXXXXXXXXXXX 我们已经见过$* 和 $1, $2 ... $9 等特殊变量这些特殊变量包含了用户从命令行输入的参数。迄今为止我们仅仅了解了一些简单的命令行语法比如一些强制性的参数和查看帮助的-h选项。但是在编写更复杂的程序时您可能会发现您需要更多的自定义的选项。通常的惯例是在所有可选的参数之前加一个减号后面再加上参数值 (比如文件名)。 有好多方法可以实现对输入参数的分析但是下面的使用case表达式的例子无疑是一个不错的方法。 #!/bin/shhelp()
{cat HELPThis is a generic command line parser demo.USAGE EXAMPLE: cmdparser -l hello -f -- -somefile1 somefile2
HELPexit 0
}while [ -n $1 ]; do
case $1 in-h) help;shift 1;; # function help is called-f) opt_f1;shift 1;; # variable opt_f is set-l) opt_l$2;shift 2;; # -l takes an argument - shift by 2--) shift;break;; # end of options-*) echo error: no such option $1. -h for help;exit 1;;*) break;;
esac
doneecho opt_f is $opt_f
echo opt_l is $opt_l
echo first arg is $1
echo 2nd arg is $2 你可以这样运行该脚本 cmdparser -l hello -f -- -somefile1 somefile2 返回结果如下 opt_f is 1
opt_l is hello
first arg is -somefile1
2nd arg is somefile2 这个脚本是如何工作的呢脚本首先在所有输入命令行参数中进行循环将输入参数与case表达式进行比较如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例首先输入的应该是包含减号的参数。 Shell脚本示例 一般编程步骤 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 现在我们来讨论编写一个脚本的一般步骤。任何优秀的脚本都应该具有帮助和输入参数。写一个框架脚本framework.sh该脚本包含了大多数脚本需要的框架结构是一个非常不错的主意。这样一来当我们开始编写新脚本时可以先执行如下命令 cp framework.sh myscript然后再插入自己的函数。 让我们来看看如下两个示例。 二进制到十进制的转换 脚本 b2d 将二进制数 (比如 1101) 转换为相应的十进制数。这也是一个用expr命令进行数学运算的例子 #!/bin/sh
# vim: set sw4 ts4 et:
help()
{cat HELPb2d -- convert binary to decimalUSAGE: b2d [-h] binarynumOPTIONS: -h help textEXAMPLE: b2d 111010
will return 58
HELPexit 0
}error()
{# print an error and exitecho $1exit 1
}lastchar()
{# return the last character of a string in $rvalif [ -z $1 ]; then# empty stringrvalreturnfi# wc puts some space behind the output this is why we need sed:numofcharecho -n $1 | wc -c | sed s/ //g # now cut out the last charrvalecho -n $1 | cut -b $numofchar
}chop()
{# remove the last character in string and return it in $rvalif [ -z $1 ]; then# empty stringrvalreturnfi# wc puts some space behind the output this is why we need sed:numofcharecho -n $1 | wc -c | sed s/ //g if [ $numofchar 1 ]; then# only one char in stringrvalreturnfinumofcharminus1expr $numofchar - 1# now cut all but the last char:rvalecho -n $1 | cut -b -$numofcharminus1 #原来的 rvalecho -n $1 | cut -b 0-${numofcharminus1}运行时出错.#原因是cut从1开始计数应该是cut -b 1-${numofcharminus1}
}while [ -n $1 ]; do
case $1 in-h) help;shift 1;; # function help is called--) shift;break;; # end of options-*) error error: no such option $1. -h for help;;*) break;;
esac
done# The main program
sum0
weight1
# one arg must be given:
[ -z $1 ] help
binnum$1
binnumorig$1while [ -n $binnum ]; dolastchar $binnumif [ $rval 1 ]; thensumexpr $weight $sumfi# remove the last position in $binnumchop $binnumbinnum$rvalweightexpr $weight * 2
doneecho binary $binnumorig is decimal $sum
# 该脚本使用的算法是利用十进制和二进制数权值 (1,2,4,8,16,..)比如二进制10可以这样转换成十进制 0 * 1 1 * 2 2 为了得到单个的二进制数我们是用了lastchar 函数。该函数使用wc –c计算字符个数然后使用cut命令取出末尾一个字符。Chop函数的功能则是移除最后一个字符。 文件循环拷贝 你可能有这样的需求并一直都这么做将所有发出邮件保存到一个文件中。但是过了几个月之后这个文件可能会变得很大以至于该文件的访问速度变慢下面的脚本 rotatefile 可以解决这个问题。这个脚本可以重命名邮件保存文件假设为outmail为outmail.1而原来的outmail.1就变成了 outmail.2 等等... #!/bin/sh
# vim: set sw4 ts4 et:ver0.1
help()
{cat HELProtatefile -- rotate the file nameUSAGE: rotatefile [-h] filenameOPTIONS: -h help textEXAMPLE: rotatefile outThis will e.g rename out.2 to out.3, out.1 to out.2, out to out.1[BR]and create an empty out-fileThe max number is 10version $verHELPexit 0
}error()
{echo $1exit 1
}while [ -n $1 ]; docase $1 in-h) help;shift 1;;--) break;;-*) echo error: no such option $1. -h for help;exit 1;;*) break;;esac
done# input check:
if [ -z $1 ] ; thenerror ERROR: you must specify a file, use -h for help
fifilen$1
# rename any .1 , .2 etc file:
for n in 9 8 7 6 5 4 3 2 1; doif [ -f $filen.$n ]; thenpexpr $n 1echo mv $filen.$n $filen.$pmv $filen.$n $filen.$pfi
done# rename the original file:
if [ -f $filen ]; thenecho mv $filen $filen.1mv $filen $filen.1
fiecho touch $filen
touch $filen 这个脚本是如何工作的呢在检测到用户提供了一个文件名之后首先进行一个9到1的循环文件名.9重命名为文件名.10文件名.8重命名为文件名. 9……等等。循环结束之后把原始文件命名为文件名.1同时创建一个和原始文件同名的空文件touch $filen 脚本调试 最简单的调试方法当然是使用echo命令。你可以在任何怀疑出错的地方用echo打印变量值这也是大部分shell程序员花费80%的时间用于调试的原因。Shell脚本的好处在于无需重新编译而插入一个echo命令也不需要多少时间。 shell也有一个真正的调试模式如果脚本strangescript出错可以使用如下命令进行调试 sh -x strangescript上述命令会执行该脚本同时显示所有变量的值。 shell还有一个不执行脚本只检查语法的模式命令如下 sh -n your_script这个命令会返回所有语法错误。 我们希望你现在已经可以开始编写自己的shell脚本了尽情享受这份乐趣吧 :) 转载声明: 本文转自 http://wiki.ubuntu.org.cn/Shell%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80转载于:https://www.cnblogs.com/wdpp/archive/2010/02/25/2386989.html