前些日子一直在想个问题:怎样用Makefile只执行一个命令,就把我VMlinux上的文件备份到Win
make bak
当然由于Linuxwin天生的不合,若是不用samba 还真想不出用什么来实现了(e_e)
思路是这样的:

现在WIN上建文件,设置(比如e:/MyProject)共享,
为了安全给共享设置用户和权限,比如用户名Guest,密码zanget
(
设置Guest密码的步骤为:我的电脑上点击右键->管理->本地用户和组->用户->右键选择Guest->设置密码)
当然读写权限都必须给Guest

然后就是Makefile的事情了。代码如下:

 

1.  bak : 

2.                  prjName=$(shell basename `pwd`);/

3.                  bakfile=$$prjName-`date +%Y%m%d.%H%M%S`.tar.gz;/

4.                  if [ ! -e ../bak/$$prjName ]; then mkdir -p ../bak/$$prjName; fi;/

5.                   cd .. && tar zcvf  bak/$$bakfile  $$prjName > /dev/null;/

6.                   if [ ! -e /mnt/win ]; then mkdir /mnt/win; fi;/

7.                    mount -t smbfs -o username=Guest,password=zanget //172.16.17.62/MyProject /mnt/win &&/

8.                   if [ ! -e /mnt/win/$$prjName ]; then mkdir /mnt/win/$$prjName; fi&&/

9.                   cp bak/$$bakfile /mnt/win/$$prjName &&/

10.     umount /mnt/win

 

 

 

 

 

 

 

解释:
1.
一般Makefile是放在某个工程文件目录下面的,这个文件目录可称为工程名prjName,这样写可通过shell获取到目录名,这样Makefile移植性会很好(放在那个工程文件下都可不需要因为工程名变化而修改了)

 

2.bakfile是通过date命令获取到例如20080920.145719格式的唯一文件名。

 

3.然后在和 工程文件同目录 的路径下 创建/bak/$$prjName目录(若目录不存在),用于存放备份文件。

 

4.打包并压缩工程文件目录 下所有文件,并存放到 3.中创建的目录下,文件名在1.中定义。

 

5.判断是否/mnt/win存在,否则创建目录,用于挂载。

 

6.挂载,并指定在WIN上设定的用户名和密码和5.中创建的挂载目录。

 

7.判断WIN e:/MyProject$$prjName是否存在,若不存在则创建之。

 

8.4.中产生的文件拷贝到WIN e:/MyProject $$prjName目录下。

 

9.卸载6.中挂载的smbfs文件系统。

 

疑难:
    a.$$prjName
$prjName不同,参考我的另外一篇文章。

    

    b.尾部的“/”是必须的,若去掉“/”Make将启动多个shell进程去执行,这样前面定义的变量prjNamebakfile将在子shell中不可见,对它们的引用将都得到空值。

    

    c.prjName=$(shell basename `pwd`)这样的定义不能放到除了 这个代码块 的其他地方,否则对其用shell变量的应用方式会得到b.(空值)的结果

(放到其他地方,可作为Makefile中的变量来引用$prjName,但是bakfile的处理就不如意了:每次对$prjName的引用,都会用`date +%Y%m%d.%H%M%S`这样的shell的命令来代替,换言之,每次都可能得到不同的文件名的结果:因为这个变量本身是由date计算得到的,可想像,若是步骤4-8的执行超过1s,则8.cp命令将不会成功(为何呢?))

(ps:最开始我就是一直吧这2个变量的定义放到 文件最开始,但是的到的结果总不能令人满意)

 

bug
    若是6.成功 而 7./8.中有执行失败的,则Make不会去执行 9. 这样就倒是挂载的目录/mnt/win 没有被卸载,这样会导致其他系统问题,这个我到是没想到有什么好点方法解决。 

 

 

Logo

更多推荐