shell编程实战——Learn|shell编程实战——Learn By Example
shell编程实战——Learn By Example 2010-11-16 星期二 清冷 一直都是在命令行上使用shell命令,但是却没有写过shell脚本,今天刚好要将国际站的所有代码拉到本地grep看修改点。人肉肯定是不行的,分支实在太多了,写个shell脚本吧^_^ svncotrunk.sh
#!/bin/bash### 从svn上将指定的SVN URL递归将所有应用的trunk(有时间改成支持pattern)分支co到本地目录 ###
# 例如: svnco http://svn.alibaba-inc.com/repos/ali_intl/apps/intl-biz/escrow/ destdir(目标根目录,默认是当前目录)
#
#输入:svnurl
#操作:将给定URL的所有应用拉到本地某个目录(默认是当前目录)
#算法:
# 如果svnurl包含trunk,则直接svn co svnurl substr(svnurl)/trunk
# 否则如果svnurl包含branch/tags,则直接忽略(因为branch/tags分支太多了,需要额外信息明确要co的分支)
# 否则,说明这是在上层目录中,对svnurl的每个子目录,递归做上面的操作(递归终止条件:svnurl含有branch/tags/trunk 或者 > maxdepth=5)## Shell脚本中的函数必须先定义后调用,一般把函数定义都写在脚本的前面,把函数调用和其它命令写在脚本的最后
## 参数:当一个函数被调用时,脚本程序的位置参数$*、$@、$#、$1, $2, ..等会被替换成函数的参数。这个跟shell的命令行参数是一样的处理方式。当函数执行完毕,这些参数会恢复它们先前的值。
## 局部变量:可以使用local关键字在shell函数中声明局部变量,局部变量将局限在函数的作用范围内。
## 返回值:如果在函数里没有使用return命令指定一个返回值,函数返回的就是执行的最后一条命令的退出码;
如果return后面跟一个数字则表示函数的Exit Status。shell的函数返回值只能是整数,作为函数的退出状态,and this exit status is assigned to the variable $?.## 检查给字符串是不是以某个子字符串结尾
end_with()
{
local src=https://www.it610.com/article/$1
local pattern=$2ret=`echo $src | grep $pattern$`if [ -z"$ret" ] #not found
then
return 1
else
return 0
fi
}## 检查给定字符串是不是包含指定子字符串
# 这里用来判断是否包含/trunk/tags/branches
contains()
{
local src=https://www.it610.com/article/$1
local pattern=$2
ret=`echo $src | grep $pattern` if [ -z"$ret" ] #not found
then
return 1
else
return 0
fi
}## 从svnurl中获取保存本地的目录名
## 如:http://svn.alibaba-inc.com/repos/ali_intl/apps/intl-biz/escrow/trunk/ ==> ali_intl/apps/intl-biz/escrow/
##http://svn.alibaba-inc.com/repos/ali_intl/apps/intl-biz/escrow/trade/trunk/biztrade/ ==> ali_intl/apps/intl-biz/escrow/trade/biztrade/
get_path_from_svnurl()
{
local svnurl=$1
echo $svnurl | sed 's#http://svn.alibaba-inc.com/repos/##' | sed 's#trunk/##'
}get_svncourl_from_svnurl()
{
local svncourl=$1
svncourl=${svncourl%%trunk*}
local TRUNK="trunk/"
echo $svncourl$TRUNK
}### 从svn上将指定的SVN URL递归将所有应用的trunk(有时间改成支持pattern)分支co到本地目录 ###
# 例如: svnco http://svn.alibaba-inc.com/repos/ali_intl/apps/intl-biz/escrow/ destdir(目标根目录,默认是当前目录)
function svncotrunk(){
#为了方便后面的判断和子svnurl拼接
if end_with $1 "/";
then
local svnurl="$1"
else
local svnurl="$1/"
fi local depth=$2 # 超过递归最大层次,退出
if [ $depth -lt 0 ];
then
datetime=`date +"%y-%m-%d %H:%M:%S"`
echo "$datetime ERROR: Recursive depth exceed $MAX_DEPTH for $svnurl"
echo "$datetime ERROR: Recursive depth exceed $MAX_DEPTH for $svnurl" >> $SVN_CO_LOG
return 1
fi# 注意Shell中的函数调用不写括号,否则会报错;参数之间是用空格隔开,而不是逗号
# Remember that the exit status of zero is a true condition in shell programming.
if contains $svnurl "/archived/";
then
echo "Ignore archived url"
elif contains $svnurl "/trunk/";
then
# 从svnurl中截取以trunk/结尾的那部分url
local svncourl=`get_svncourl_from_svnurl $svnurl`
# 保存分支到一个统计文件
datetime=`date +"%y-%m-%d %H:%M:%S"`
echo "$datetime==>$svncourl" >> $SVN_CO_LOG
local path=`get_path_from_svnurl $svncourl`
svn co $svncourl $path
elif contains $svnurl "/branches/" || contains $svnurl "/tags/" || contains $svnurl "/milestone/";
then
echo "This is a branch or tag or milestone, we don't deal with braches or tags or milestone right now!"
else
subdirs=`svn ls $svnurl`
for subdir in $subdirs;
do
subsvnurl=$svnurl$subdir
# Recursive
svncotrunk $subsvnurl `expr $depth - 1`#注意减号两旁必须有空格,否则会被当作字符串拼接
done
fi
}MAX_DEPTH=8# we have less than 1 argument. Print the help text:
if [ $# -lt 1 ];
then
cat<< HELPNAME
svncotrunk -- 从svn上将指定的SVN URL递归将所有子分支的trunk分支co到本地目录
SYNOPSTS
svncotrunk svnurl [svnco.log path] [depth=8]
DESCRIPTION
从svn上将指定的SVN URL递归将所有子分支的trunk分支co到本地目录, 将svn co分支保存在svnco.log文件中(如果没有指定文件,默认是当前目录下的svnco.log)例如: svncotrunk http://svn.alibaba-inc.com/repos/ali_intl/apps/intl-biz/escrow/ cohistory.logHELP
exit 0
elif [ $# -eq 1 ];
then
SVN_CO_LOG="svnco.log"
svncotrunk $1 MAX_DEPTH
elif [ $# -eq 2 ];
then
SVN_CO_LOG=$2
svncotrunk $1 $MAX_DEPTH
elif [ $# -ge 3 ];
then
MAX_DEPTH=$3
svncotrunk $1 $MAX_DEPTH
fi
【shell编程实战——Learn|shell编程实战——Learn By Example】
关于函数和返回值 法一: 使用 return 这个命令,把函数中某个数值返回,其实是使用Exist Status作为返回值,使用$?接收返回值 法二: 在函数中使用 echo 输出想要返回的结果,使用`function call`接收函数输出结果。 Output can be in the form of stdout or a return code value or both.
这两者往往是结合在一起的,如果你不想显示在stdout中显示函数的echo值,可以采用function > /dev/null将函数的echo输出到黑洞中。
参考资料: 1. Shell 编程中的函数返回值http://hi.baidu.com/jidongxx/blog/item/03d06bf07e8049a2a50f5237.html 2. Functionshttp://www.injunea.demon.co.uk/pages/page212.htm 3. 13. Functionshttp://steve-parker.org/sh/functions.shtml 4. Chapter 6. Exit and Exit Statushttp://www.faqs.org/docs/abs/HTML/exit-status.html
推荐阅读
- Shell-Bash变量与运算符
- python青少年编程比赛_第十一届蓝桥杯大赛青少年创意编程组比赛细则
- 《机器学习实战》高清中文版PDF英文版PDF+源代码下载
- HTML基础--基本概念--跟着李南江学编程
- --木木--|--木木-- 第二课作业#翼丰会(每日一淘6+1实战裂变被动引流# 6+1模式)
- 我的软件测试开发工程师书单
- Linux|109 个实用 shell 脚本
- 芯灵思SinlinxA33开发板Linux内核定时器编程
- 关于响应式编程的十个问题
- 2020-07-29《吴军·阅读与写作50讲》24实战才能转化效能