加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

$(MAKE) -C $$dir; \

(2011-10-16 10:50:57)
标签:

it

分类: makefile

# Set shell to bash if possible, otherwise fall back to sh

SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \

       else if [ -x /bin/bash ]; then echo /bin/bash; \

       else echo sh; fi; fi)

       "$$BASH"的作用实质上是生成了字符串“$BASH”(前一个$号的作用是指明第二个$是普通的字符)。若执行当前 Makefile的shell中定义了“$BASH”环境变量,且文件“$BASH”是可执行文件,则SHELL的值为“$BASH”。否则,若 “/bin/bash”是可执行文件,则SHELL值为“/bin/bash”。若以上两条都不成立,则将“sh”赋值给SHELL变量。

       由于作者的机器安装了bash shell,且shell默认环境变量中定义了“$BASH”,因此SHELL 被设置为$BASH 


1. 如果我们需要书写这样一个规则:规则所定义的命令不是去创建目标文件,而是使用make指定具体的目标来执一些特定的命令。像下边那样:

clean:

rm *.o temp

规则中“rm”不是创建文件“clean”的命令,只是删除当前目录下的所有.o文件和temp文件。在工作目录下不存在“clean”这个文件时,我们输入“make clean”后,“rm *.o temp”总会被执行。这是我们的初衷。

但当前工作目录下存在文件“clean”时情况就不一样了,在我们输入“make clean”时。规则没有依赖文件,所以目标被认为是最新的而不去执行规则作定义的命令,命令“rm”将不会被执行。这并不是我们的初衷。为了避免这个问题,我们可以将目标“clean”明确的声明为伪目标。将一个目标声明为伪目标需要将它作为特殊目标.PHONY”的依赖。如下:

.PHONY : clean

这样目标“clean”就是一个伪目标,无论当前目录下是否存在“clean”这个文件。我们输入“make clean”之后。“rm”命令都会被执行。而且,当一个目标被声明为伪目标后,make在执行此规则时不会试图去查找隐含规则来创建这个目标。这样也提高了make的执行效率,同时我们也不用担心由于目标和文件名重名而使我们的期望失败。在书写伪目标规则时,首先需要声明目标是一个伪目标,之后才是伪目标的规则定义。目标“clean”书写格式应该如下:

.PHONY: clean

clean:

rm *.o temp

2. 伪目标的另外一使用场合在make的并行和递归执行过程中。此情况下一般存在一个变量,其定义为所有需要make的子目录。对多个目录进行make的实现方式可以在一个规则中可以使用shell的循环来完成。如下:

SUBDIRS = foo bar baz

subdirs:

for dir in $(SUBDIRS); do \

$(MAKE) -C $$dir; \

done

但这种实现方法存在以下几个问题。1. 当子目录执行make出现错误时,make不会退出。就是说,在对某一个目录执行make失败以后,会继续对其他的目录进行make。在最终执行失败的情况下,我们很难根据错误的提示定位出具体是是那个目录下的Makefile出现错误。这给问题定位造成了很大的困难。为了避免这样的问题,我们可以在命令行部分加入错误的监测,在命令执行错误后make退出。不幸的是,如果在执行make时使用了“-k”选项,此方式将失效。2. 另外一个问题就是使用这种shell的循环方式时,没有用到make对目录的并行处理功能,因为规则的命令是一条完整的shell命令,不能被并行的执行。

我们可以通过伪目标方式来克服以上实现方式所存在的两个问题。

SUBDIRS = foo bar baz

.PHONY: subdirs $(SUBDIRS)

subdirs: $(SUBDIRS)

$(SUBDIRS):

$(MAKE) -C $@

foo: baz

上边的实现中使用了一个没有命令行的规则“foo: baz”,用来限制子目录的make顺序。此规则的含义时在处理“foo”目录之前,需要等待“baz”目录处理完成。在书写一个并行执行make的Makefile时,目录的处理顺序是需要特别注意的。




head
格式: head [option] .. [FILE]..

当需要查看一个文本文件的头部或尾部时,head 命令及tail 命令可以非常方便的完成该操作。head 命令用于查看一个文本文件的开头部分;而tail 命令则用于显示文本文件的末尾几行。

(1)-c, --bytes=[-]N

     打印每个文件的前N个字节,如果N前面加上-,那么就打印每个文件的除了最后N个字节外的所有字节

(2)-n, --lines=[-]N

     打印前N行,如果N前加上[-]则打印除了最后N行数据外的所有行

(3)-q, --quiet, --silent

(4)-v, –verbose

举例:
head example.txt 显示文件 example.txt 的前十行内容;
head -n 20 example.txt 显示文件 example.txt 的前二十行内容;

tail

和head相反,输出文件的后部数据。

(1)-c , --byte=K

输出最后k bytes的内容,如果使用 –c +K则输出从第K byte后的所有内容。

(2)-f, --follow[={name|descriptor}]

当文件增长时,输出新增的内容

(2)-n, --lines=K

输出后K行,如果使用-n +K则会输出从第K行开始的所有行

(3)--max-unchanged-stats=N

重新打开一个在N次迭代后没有改变大小的文件,查看它是否已经unlinked或者重命名了。

(4)--pid=PID

和-f搭配使用,在进程PID终止后退出。

(5)--retry

不断打开一个文件,即使它当前不可以访问,和—follow=name 一起使用

例子:

tail example.txt 显示文件 example.txt 的后十行内容;
tail -n 20 example.txt 显示文件 example.txt 的后二十行内容;
tail -f example.txt 显示文件 example.txt 的后十行内容并在文件内容增加后,自动显示新增的文件内容。
注意:
最后一条命令非常有用,尤其在监控日志文件时,可以在屏幕上一直显示新增的日志信息。




for i in a b c 字符串列表A B C
字符串用空格分隔,没有括号,没有逗号, 然后循环将其依次赋给变量i
变量没有$
do
echo "i is $i"
done
[macg@machome ~]$ sh test.sh
i is a
i is b
i is c

cut的横向定位:
cut-c m-nfile  表示显示每一行的第m个字元到第n个字元,如果有过个区域,用,隔开如: cut -c 3-9,12-20 file
cut -d: -f 1 /etc/passwd -d是分隔符,默认的是TAB,也定义其他的:如cut -d'|' 1.test用|做分隔符,可以用“”;
f1表示每一行的第一个字段(和awk的域概念类似),f2-5,每一行的2-5个字段
cut的纵向定位
cut -b list [-n] [file ...]      cut -c list [file ...]  cut -f list [-d delim][-s][file ...]
上面的-b、-c、-f分别表示字节、字符、字段(即byte、character、field);list表示-b、-c、-f操作范围,-n常常表示具体数字;
file表示的自然是要操作的文本文件的名称;delim(英文全写:delimiter)表示分隔符,默认情况下为TAB;
 -s表示不包括那些不含分隔符的行(这样有利于去掉注释和标题)
范围的表示方法:N   只有第N项      N- 从第N项一直到行尾     N-M 从第N项到第M项(包括M)
-M 从一行的开始到第M项(包括M)    - 从一行的开始到结束的所有项

0

阅读 收藏 喜欢 打印举报/Report
前一篇:特殊的宏
后一篇:$(RANLIB) $@
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有