来自:https://blog.csdn.net/caoyoubarili/article/details/73251957
Makefile VS shell
首先说说Makefile是不是脚本?
其实Makefile和shell一样都是写完就可以运行,无需编译,所以只要不是在进行计算机等级考试,那么,就当脚本吧,何必苦苦分析其归属呢,反正都是Linux的子孙后代。
Makefile和shell 紧密相连,而且众多语法类似但又有其区别,所以很多兄弟姐妹们都苦于编写时的种种异常,以下我就列出比较普遍且很重要的语法特点进行比较吧。
一.Makefile和Shell的独角戏:
1.赋值:
Makefile:
洁癖啊,一定要用空格分开variable和Value;
Name空格=空格"Makefile"
Shell:
亲密型,variable和Value一定要紧密相连;
Name="Shell"
2.引用变量:变量都喜欢钱,所以用变量一定要给钱,“$”开头
Makefile:专一,引用变量时必须用()抱住变量,不抱住的话,变量会掉脑袋哦。
Who空格=空格$(Name)
Shell:就像shell这个英文单词,含有太多意思,太花心,所以他用变量时可以用花括号{}抱住,
甚至不抱住变量。
Who=${Name} or Who=$Name
3.判断语句:
Makefile:始终专一,"()"是他们环抱条件的唯一选择
ifeq空格($(Name), makefile)
...
else
...
endif
Shell:shell又变心了,开始用"[]"限制条件,刻薄的中括号,使每一个条件都需要空格分离,实在
是太花心,所以还需要用"then"多考虑一下该选择哪一个。
if空格[空格expression空格]
then
...
else
....
fi
二.Makefile和Shell神交时:
Makefile对Shell既是喜欢又有禁锢,爱的颇纠结啊。
典型的MakeFile文法结构:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Name ="Makefile"
target ... :prerequisites ...
command
Shell脚本
...
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1.Makefile留给shell的行宫(target)
注意啰:shell语句只能用在target目标中哦。写在其他地方,Makefile对他是置之不理的;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Name ="Makefile"
echo$(Name) //echo你好淘气哦,你只能在target中生效,在这里是不会有任何输出的哦。
target ... :prerequisites ...
echo${Name} //在这里就是小乖乖了;Target是shell的一片净土,Shell的花心语法可以
完全应用其中;看到没,引用这个Makefile定义的变量,使用了shell
的语法“{}”;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2.Shell在Makefile行宫中受到的限制
记得Makefile是有洁癖的家伙吧,所以怎么可能让shell在行宫中自由散漫呢;
请看Makefile以下的手段:
Target中的每一行Shell语句将以独立的进程运行;
如果下一行再执行一个Shell语句,那么将创建新的进程;两行的Shell语句没有交互性;
如果两行的shell想相互关联,那么请将 ";\"放在行尾。
看看以下经典例子吧:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Name ="Makefile"
target ... :prerequisites ...
Name="shell" //看起来Name的Value被修改了,可真是这样吗?
echo${Name} //echo出的结果还是“Makefile”,因为上一句的修改,被控制在了那一
行所对应的Shell进程中,不会影响到Makefile中的Name。
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Name ="Makefile"
target ... :prerequisites ...
Name="shell";\ //看到没,用";\"将三行连接起来,形成了一行Shell脚本。
echo${Name};\ //echo出的结果还是“Makefile”,因为此句输出的是Makefile中的Name,
如果想用Shell自己定义的Name,没那么容易哦,天下没有免费的午餐,
请看下一句;
echo$${Name}; //MakeFile给了Shell在行宫中引用Shell自己变量的方法,多付点美钞
钱吧,“$$”开头就可以了,这样echo出的结果就是"shell"了
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Linux Makefile与shell脚本区别
来自:https://blog.csdn.net/gx19862005/article/details/40375909
在Makefile可以调用shell脚本,但是Makefile和shell脚本是不同的。本文试着归纳一下Makefile和shell脚本的不同。
1、 shell中所有引用以$打头的变量其后要加{},而在Makefile中的变量是以$打头的后加()。实例如下:
Makefile:
PATH="/data/"
SUBPATH=$(PATH)
Shell:
PATH="/data/"
SUBPATH=${PATH}
2、Makefile中所有以$打头的单词都会被解释成Makefile中的变量。如果你需要调用shell中的变量(或者正则表达式中锚定句位$),都需要加两个$符号($$)。Makfile实例如下:
PATH="/data/"
all:
echo ${PATH}
echo $$PATH
例子中的第一个${PATH}引用的是Makefile中的变量,而不是shell中的PATH环境变量,后者引用的是Shell中的PATH环境变量。
3、通配符区别
shell 中通配符*表示所有的字符
Makefile 中通配符%表示所有的字符
4、在Makefile中只能在target中调用Shell脚本,其他地方是不能输出的。比如如下代码就是没有任何输出:
VAR="Hello"
echo "$VAR"
all:
.....
以上代码任何时候都不会输出,而且还会报错,如下:Makefile:*** command commence before first target.Stop,因为没有在target内。如果上述代码改为如下:
VAR="Hello"
all:
echo "$VAR"
.....
以上代码,在make all的时候将会执行echo命令,同时必须注意echo "$VAR"之前必须有一个table,这样Makefile才会认为其为一条command,如果没有table会报错如下:Makefile:*** missing separator.Stop.
5、在Makefile中执行shell命令,一行创建一个进程来执行。这也是为什么很多Makefile中有很多行的末尾都是“; \”,以此来保证代码是一行而不是多行,这样Makefile可以在一个进程中执行,例如:
SUBDIR=src example
all:
@for subdir in $(SUBDIR); \
do\
echo "building "; \
done
上述可以看出for循环中每行都是以”; \”结尾的。
6、获取当前目录
PATH=`pwd` 注意是``,不是''
7、shell总=两边不允许有空格,Makfile中=两边允许有空格。
makefile中的shell语法
在Makefile中写shell代码有点诡异,和一般的shell语法不太一样,如果不了解,看Makefile会莫名其妙。下面总结了一些。
1:在Makefile文件的目标项冒号后的另起一行的代码才是shell代码,并且另起一行的代码前面要有Table制表符,这样才会认为是shell代码,例如:
xx = xx1 //这里是makefile代码
yy :xx = xx2 //这是是makefile代码,makefile允许变量赋值时,“=”号两边留空格
yy: //这是目标项
xx=xx3 //只有这里是shell代码 ,shell不允许‘=’号两边有空格,xx=xx3前面至少有一个Table制表符
2: 有一个例外:
xx=$(shell 这里的代码也是shell代码)
例如:
$(echo hello)
2:Makefile中的shell,每一行是一个进程,不同行之间变量值不能传递。所以,Makefile中的shell不管多长也要写在一行,例如:
SUBDIR=src example all: @for subdir in $(SUBDIR); / // 这里往下是一行shell do/ echo "building " $$subdir; / done |
3:Makefile中的变量以$开头, 所以,为了避免和shell的变量冲突,shell的变量以$$开头
例子1:从当前目录路径中提取出 /application 或 /base_class 之前的部分
PROJECT_ROOT_DIR = $(shell pwd | awk -F'/application|/base_class' '{print $$1}')
例子2:上例中$$subdir就是shell中的变量, 而$(SUBDIR)是Makefile的中的变量
shell编程:http://wenku.baidu.com/view/75effa22ccbff121dd36834a.html