Linux下把多个子目录中的源代码添加到CVS仓库的Bash脚本

Linux下把多个子目录中的源代码添加到CVS仓库的Bash脚本

本文链接:http://codingstandards.iteye.com/blog/792113    (转载请注明出处)

要求描述

  在src目录下,包含多个子目录,每个子目录下都有C/C++的源代码,现在要把它们自动加入到CVS仓库中,只能将源文件(比如.h文件,.c文件,.hpp文件,.cpp文件,makefile)提交,不能包含编译中间产生的临时文件(比如.o文件)和最终执行文件。

  当把一个目录添加CVS仓库之后,目录中会增加一个CVS目录,CVS目录中的几个文件(Entries、Repository和Root)是用来保存一些cvs版本管理信息的。要注意的是cvs这个东西有个问题,使用cvs add CVS时也可以将CVS这个目录添加到CVS仓库中,因此要避免这种情况。

版本演化

版本0

基本思路:遍历每一个子目录,CVS目录除外,如果一个子目录中没有CVS子目录,那么需要添加该目录,否则忽略;然后把该子目录下的源文件添加到CVS仓库中。如下所示:

文件:add2cvs0.sh

#!/bin/sh

for d in *
do
	if [ -d "$d" -a "$d" != "CVS" ]; then
		if [ ! -d "$d/CVS" ]; then
			cvs add "$d"
		fi
		cvs add "$d/*.h" "$d/*.c" "$d/*.hpp" "$d/*.cpp" "$d/makefile" "$d/*.java" "$d/*.html"
	fi
done
cvs commit

试一下,发现它会把*.h本身作为一个文件名传递给cvs add命令,实际上并不是每个目录中都包含这几种扩展名的文件。因为有些是纯C编写的,有些是用C++的。

[root@rhel55 src]# ./add2cvs0.sh
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test0/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test1/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test2/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test3/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test4/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test5/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test6/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test7/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test8/*.h,v: Invalid argument
cvs commit: Examining .
cvs commit: Examining test0
cvs commit: Examining test1
cvs commit: Examining test2
cvs commit: Examining test3
cvs commit: Examining test4
cvs commit: Examining test5
cvs commit: Examining test6
cvs commit: Examining test7
cvs commit: Examining test8
[root@rhel55 src]#

版本1

改进思路:把cvs add 后面的那几种通配符表示的文件名,改用Bash中的大括号表示。比如*.{h,c}实际相当于$.h *.c的简写法。

文件:add2cvs1.sh

#!/bin/sh

for d in *
do
	if [ -d "$d" -a "$d" != "CVS" ]; then
		if [ ! -d "$d/CVS" ]; then
			cvs add "$d"
		fi
		#cvs add "$d/*.h" "$d/*.c" "$d/*.hpp" "$d/*.cpp" "$d/makefile" "$d/*.java" "$d/*.html"
		cvs add $d/*.{h,c,hpp,cpp,java,html,xml}
	fi
done
cvs commit

试一下,还是不行,跟上面一样。因为只是把参数改一下写法,实际上是等同的。

[root@rhel55 src]# ./add2cvs1.sh
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test0/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test1/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test2/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test3/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test4/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test5/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test6/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test7/*.h,v: Invalid argument
cvs [server aborted]: Couldn't open RCS file /CVSWEBX/web_spider/src/test8/*.h,v: Invalid argument
cvs commit: Examining .
cvs commit: Examining test0
cvs commit: Examining test1
cvs commit: Examining test2
cvs commit: Examining test3
cvs commit: Examining test4
cvs commit: Examining test5
cvs commit: Examining test6
cvs commit: Examining test7
cvs commit: Examining test8
[root@rhel55 src]#

版本2

改进思路:直接使用通配符表示的文件参数(比如*.h)在传递的时候,如果没有可以匹配的文件,那么Bash就会把该参数本身传递。因此想到先用ls命令把这些文件列出来,把输出作为参数来传递。

文件:add2cvs2.sh

#!/bin/sh

for d in *
do
	if [ -d "$d" -a "$d" != "CVS" ]; then
		if [ ! -d "$d/CVS" ]; then
			cvs add "$d"
		fi
		#cvs add "$d/*.h" "$d/*.c" "$d/*.hpp" "$d/*.cpp" "$d/makefile" "$d/*.java" "$d/*.html"
		cvs add $(ls $d/*.{h,c,hpp,cpp,java,html,xml,sh} $d/makefile)
	fi
done
cvs commit

试一下,发现效果还不错。如果匹配的文件不存在,ls会报错,错误信息是输出在标准错误设备上的,而$(ls *.h)只把标准输出的信息变成字符串。

[root@rhel55 src]# ./add2cvs2.sh
ls: test0/*.h: 没有那个文件或目录
ls: test0/*.hpp: 没有那个文件或目录
ls: test0/*.cpp: 没有那个文件或目录
ls: test0/*.java: 没有那个文件或目录
ls: test0/*.html: 没有那个文件或目录
ls: test0/*.xml: 没有那个文件或目录
ls: test0/makefile: 没有那个文件或目录
cvs server: test0/test0.c already exists, with version number 1.1
cvs server: test0/test0.sh already exists, with version number 1.1
ls: test1/*.h: 没有那个文件或目录
ls: test1/*.c: 没有那个文件或目录
ls: test1/*.hpp: 没有那个文件或目录
ls: test1/*.java: 没有那个文件或目录
ls: test1/*.html: 没有那个文件或目录
ls: test1/*.xml: 没有那个文件或目录
cvs server: test1/makefile already exists, with version number 1.1
cvs server: test1/test1.cpp already exists, with version number 1.1
cvs server: test1/test1.sh already exists, with version number 1.1
ls: test2/*.h: 没有那个文件或目录
ls: test2/*.c: 没有那个文件或目录
ls: test2/*.hpp: 没有那个文件或目录
ls: test2/*.java: 没有那个文件或目录
ls: test2/*.html: 没有那个文件或目录
ls: test2/*.xml: 没有那个文件或目录
ls: test2/*.sh: 没有那个文件或目录
cvs server: test2/makefile already exists, with version number 1.1
cvs server: test2/test2.cpp already exists, with version number 1.1
ls: test3/*.h: 没有那个文件或目录
ls: test3/*.c: 没有那个文件或目录
ls: test3/*.hpp: 没有那个文件或目录
ls: test3/*.java: 没有那个文件或目录
ls: test3/*.html: 没有那个文件或目录
ls: test3/*.xml: 没有那个文件或目录
ls: test3/*.sh: 没有那个文件或目录
cvs server: test3/makefile already exists, with version number 1.1
cvs server: test3/test3.cpp already exists, with version number 1.1
ls: test4/*.h: 没有那个文件或目录
ls: test4/*.hpp: 没有那个文件或目录
ls: test4/*.cpp: 没有那个文件或目录
ls: test4/*.html: 没有那个文件或目录
ls: test4/*.xml: 没有那个文件或目录
ls: test4/makefile: 没有那个文件或目录
cvs server: test4/test4.c already exists, with version number 1.1
cvs server: test4/Test4.java already exists, with version number 1.1
cvs server: test4/test4.sh already exists, with version number 1.1
ls: test5/*.h: 没有那个文件或目录
ls: test5/*.c: 没有那个文件或目录
ls: test5/*.hpp: 没有那个文件或目录
ls: test5/*.java: 没有那个文件或目录
ls: test5/*.html: 没有那个文件或目录
ls: test5/*.xml: 没有那个文件或目录
ls: test5/*.sh: 没有那个文件或目录
cvs server: test5/makefile already exists, with version number 1.1
cvs server: test5/test5.cpp already exists, with version number 1.1
ls: test6/*.h: 没有那个文件或目录
ls: test6/*.c: 没有那个文件或目录
ls: test6/*.hpp: 没有那个文件或目录
ls: test6/*.java: 没有那个文件或目录
ls: test6/*.xml: 没有那个文件或目录
ls: test6/*.sh: 没有那个文件或目录
cvs server: test6/index.html already exists, with version number 1.1
cvs server: test6/makefile already exists, with version number 1.1
cvs server: test6/test6.cpp already exists, with version number 1.1
ls: test7/*.h: 没有那个文件或目录
ls: test7/*.c: 没有那个文件或目录
ls: test7/*.hpp: 没有那个文件或目录
ls: test7/*.java: 没有那个文件或目录
ls: test7/*.html: 没有那个文件或目录
ls: test7/*.sh: 没有那个文件或目录
cvs server: test7/makefile already exists, with version number 1.1
cvs server: test7/spider.xml already exists, with version number 1.1
cvs server: test7/test7.cpp already exists, with version number 1.1
ls: test8/*.h: 没有那个文件或目录
ls: test8/*.c: 没有那个文件或目录
ls: test8/*.hpp: 没有那个文件或目录
ls: test8/*.java: 没有那个文件或目录
ls: test8/*.html: 没有那个文件或目录
ls: test8/*.xml: 没有那个文件或目录
ls: test8/*.sh: 没有那个文件或目录
cvs server: test8/makefile already exists, with version number 1.1
cvs server: test8/test8.cpp already exists, with version number 1.1
cvs commit: Examining .
cvs commit: Examining test0
cvs commit: Examining test1
cvs commit: Examining test2
cvs commit: Examining test3
cvs commit: Examining test4
cvs commit: Examining test5
cvs commit: Examining test6
cvs commit: Examining test7
cvs commit: Examining test8
[root@rhel55 src]#

版本3

改进思路:把ls的错误输出摒蔽掉,通过将标准错误输出重定向到/dev/null就可以做到了。

文件:add2cvs.sh

#!/bin/sh

for d in *
do
	if [ -d "$d" -a "$d" != "CVS" ]; then
		if [ ! -d "$d/CVS" ]; then
			cvs add "$d"
		fi
		#cvs add "$d/*.h" "$d/*.c" "$d/*.hpp" "$d/*.cpp" "$d/makefile" "$d/*.java" "$d/*.html"
		cvs add $(ls $d/*.{h,c,hpp,cpp,java,html,xml,sh} $d/makefile 2>/dev/null)
	fi
done
cvs commit

试一下,目标基本达到。

[root@rhel55 src]# ./add2cvs.sh 
cvs server: test0/test0.c already exists, with version number 1.1
cvs server: test0/test0.sh already exists, with version number 1.1
cvs server: test1/makefile already exists, with version number 1.1
cvs server: test1/test1.cpp already exists, with version number 1.1
cvs server: test1/test1.sh already exists, with version number 1.1
cvs server: test2/makefile already exists, with version number 1.1
cvs server: test2/test2.cpp already exists, with version number 1.1
cvs server: test3/makefile already exists, with version number 1.1
cvs server: test3/test3.cpp already exists, with version number 1.1
cvs server: test4/test4.c already exists, with version number 1.1
cvs server: test4/Test4.java already exists, with version number 1.1
cvs server: test4/test4.sh already exists, with version number 1.1
cvs server: test5/makefile already exists, with version number 1.1
cvs server: test5/test5.cpp already exists, with version number 1.1
cvs server: test6/index.html already exists, with version number 1.1
cvs server: test6/makefile already exists, with version number 1.1
cvs server: test6/test6.cpp already exists, with version number 1.1
cvs server: test7/makefile already exists, with version number 1.1
cvs server: test7/spider.xml already exists, with version number 1.1
cvs server: test7/test7.cpp already exists, with version number 1.1
cvs server: test8/makefile already exists, with version number 1.1
cvs server: test8/test8.cpp already exists, with version number 1.1
cvs commit: Examining .
cvs commit: Examining test0
cvs commit: Examining test1
cvs commit: Examining test2
cvs commit: Examining test3
cvs commit: Examining test4
cvs commit: Examining test5
cvs commit: Examining test6
cvs commit: Examining test7
cvs commit: Examining test8
[root@rhel55 src]#

猜你喜欢

转载自codingstandards.iteye.com/blog/792113