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]#