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=$1
local pattern=$2
ret=`echo $src | grep $pattern$`
if [ -z "$ret" ] #not found
then
return 1
else
return 0
fi
}
## 检查给定字符串是不是包含指定子字符串
# 这里用来判断是否包含/trunk/tags/branches
contains()
{
local src=$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<< HELP
NAME
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.log
HELP
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
关于函数和返回值
法一:使用 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输出到黑洞中。
参考资料:
分享到:
相关推荐
本书"Linux与UNIX SHELL编程指南——2"深入探讨了这一主题,提供了丰富的知识和实践指导。 首先,Shell编程的基本概念是理解所有后续学习的基础。Shell是操作系统提供的一种解释器,它接收用户输入的命令并执行。在...
Shell编程是Linux操作系统中进行系统管理和自动化任务的重要工具。它是一种命令解释器,负责解析用户输入的命令并执行。在Linux环境中,默认的Shell通常是Bash(Bourne-Again SHell),但还有其他多种Shell,如C ...
《LINUX与UNIX SHELL编程指南》是一本深入讲解Shell编程技术的专业书籍,它分为五个主要部分,旨在帮助读者掌握UNIX和LINUX环境下的Shell编程技能。以下将详细阐述书中的核心知识点: 第一部分:Shell基础 这部分...
Shell编程,即编写Shell脚本,是一种强大的工具,可以自动化日常重复任务,提高工作效率。通过学习Shell编程,你可以创建自定义的命令行工具,实现文件处理、系统管理、网络操作等各种功能。例如,可以编写一个脚...
Shell编程则是掌握这两种系统操作和自动化任务执行的重要技能。 Shell编程允许用户通过编写脚本来执行一系列命令,实现对系统资源的高效管理和自动化任务。常见的Shell有Bash(Bourne-Again SHell),它是Linux默认...
在本Linux+Shell编程课程设计中,我们将深入探讨如何利用Shell脚本来实现Linux系统的用户管理。Shell编程是Linux系统中的重要一环,它提供了一种简单而强大的方式来自动化日常的系统任务,包括用户账户的创建、修改...
"shell编程--用户信息管理(模拟)" 本课设计的主要目的是让学生掌握 Linux 操作系统中 shell 脚本编程技术的各种知识点,包括变量定义、变量使用、循环控制结构、条件选择结构、用户交互、文件读写、文本内容分析...
H5HtmlJavaScriptCSSApp, https://github.com/Romanysoft/working shell脚本入门——流程控制 shell脚本入门——流程控制 shell脚本入门——流程控制 shell脚本入门——流程控制 shell脚本入门——流程控制
在linux系统中,我们一般都是用C语言写服务端程序,但是一般我们不直接启动这个程序,而是通过一个shell脚本启动和关闭
本压缩包"Shell编程实战.zip"很可能是为了帮助用户深入理解和掌握Shell编程技能而提供的一系列教程或实例。 在Shell编程中,你将学习到以下几个核心知识点: 1. **Shell脚本基础**:了解什么是Shell脚本,如何创建...
根据提供的文件信息,我们可以推断出这是一份关于“老男孩shell高级编程实战视频”的资源分享,主要聚焦于Shell编程的高级应用与实践。接下来,我们将深入探讨与该主题相关的几个核心知识点,包括Shell编程的基本...
在linux系统中,我们一般都是用C语言写服务端程序,但是一般我们不直接启动这个程序,而是通过一个shell脚本启动和关闭
1-Shell编程课前思想-我一定要学好shell编程 2-学好Shell编程需要的必备基础 3-Shell脚本介绍及第一个规范Shell脚本说明 4-Shell编程的作用和地位 5-Shell语言的种类介绍 6-Shell的条件表达式知识初步介绍实践 7-...
读书笔记:Linux 命令行与 shell 脚本编程大全——学习仓库
主要针对shell编程的基础做一个阐述,其中包括基础的变量、常量、字符串、数组等的定义方式,一些比较运算符的详细介绍,分支判断语句、循环语句的基础用法、自定义函数的使用方法。还包括一些代码示例
从提供的文件内容来看,这是一本关于Shell脚本编程的实战教程书籍,以实例的方式教授读者如何使用Shell脚本来完成各种Linux系统运维任务。下面将详细介绍从给出的内容中能够总结出的一些Shell脚本编程知识点。 首先...
Shell编程是Linux操作系统中一种强大的命令行脚本语言,它允许用户通过编写脚本来自动化日常任务,提高工作效率。本文将深入探讨Shell编程的基础知识,帮助初学者快速入门。 首先,了解Shell是什么至关重要。Shell...
shell脚本编程,chm版本,很适合初学者
《精通UNIX Shell脚本编程》 第2个压缩包!
本书《Shell脚本编程诀窍——适用于Linux、Bash等》由Steve Parker撰写,旨在帮助读者深入理解和掌握Shell脚本的编写技巧。 Shell脚本的基础是Bash(Bourne-Again SHell),它是大多数Linux发行版的默认Shell。Bash...