AI智能
改变未来

make和shell入门


make基础

1. make的显式规则

在Linux操作系统下编程时,通常利用make命令来自动完成编译工作。Make命令根据一个称为makefile的文件来完成并自动维护编译工作。Makefile文件需要按照某种语法进行编写,其中说明了如何编译各个源文件并链接生成可执行文件,并定义了源文件之间的相互依赖关系。当修改了其中某个源文件时,如果其他源文件依赖于该文件,则也要重新编译所有依赖该文件的源文件。

Makefile文件中包含一些规则来告诉make处理哪些文件以及如何处理这些文件。规则主要是描述哪些文件(target目标文件)是从哪些别的文件(dependency依赖文件)中产生的,以及用什么命令(command)来执行这个过程。Makefile规则的一般形式如下:

target:dependencydependency(tab)  <command>

目标文件(target)通常是可执行文件或中间文件,但也可以是要执行的动作,如“clean”。依赖文件(dependency)列表通常是编译目标文件所依赖的其他文件。命令(command)是创建target文件所需要执行的步骤,比如编译命令,每个命令占一行,起始字符必须为TAB字符。

test: prog.ocode.o   gcc –o test prog.o code.oprog.o: prog.c prog.h code.h   gcc –c prog.c –o prog.ocode.o: code.c code.h   gcc –c code.c –o code.oclean:   rm –f *.o

左图的makefile示例中共定义了四个目标:test、prog.o、code.o和clean。目标文件与依赖文件用":"分隔,多个依赖文件以空格隔开,然后另起一行以tab开头给出实现目标的命令。当命令过长时,使用"\\"作为续行符。

例中已完成的程序源码为prog.c,prog.h,code.c,code.h,首先要使用make testmake(默认编译makefile文件中第一个目标)编译程序。由于test依赖的prog.o和code.o文件不存在,所以要先执行gcc –c prog.c –o prog.ogcc –c code.c –o code.o生成这2个文件。最后再执行gcc –o test prog.o code.o生成test。make clean用于清除编译过程的中间文件,这通常是约定俗成的做法。

2. make变量的用法

在一行的开始给初变量名字,后面跟一个":="及要设定的值,即可定义变量:VARNAME:=string使用时把变量用括号括起来,并在前面加上$:$

使用方法如下:

OBJS:=prog.o code.oCC:=gcctest: ${OBJS}${CC} –o test ${OBJS}prog.o: prog.c prog.h code.h${CC} –c prog.c –o prog.ocode.o: code.c code.h${CC} –c code.c –o code.oclean:rm–f *.o

Makefile文件中还可以使用环境变量,以及预定义变量,如$@(目标名)、$^(所有的依赖文件)、$<(第一个依赖文件),例如:demo.o: demo.c demo.h可以写成:gcc-c $< -o $@

3. make的隐式规则

make进行编译时遵循一些称作隐含规则的内置规则,这些规则在makefile中并没有被完整地给出,但make知道没有被给出的部分是什么。(我理解为隐式规则可以不用给出)

典型的隐含规则给出了由*.c文件如何生成*.o文件,被隐含的规则是:%.o: %.c  $ $ $< -o $@

依据上面的隐含规则,前面的变量介绍中的示例代码可以省略为如下内容:

OBJS:=prog.o code.oCC:=gccCFLAGS:=-ctest:${OBJS}${CC} –o $@ $^prog.o: prog.c prog.h code.hcode.o:code.c code.hclean:rm –f *.o

shell基础

Shell也有多种不同的版本:sh:GNU Bourne Shellbash:GNU Bourne Again Shell(PC默认)Korn Shell:大部分与BourneShell兼容。C Shell:是SUN公司Shell的BSD版本。ZShell:集成了bash、ksh的重要特性。

通常在shell程序开始声明类型,如 #!/bin/sh#!/bin/bash

1. shell的四个变量

1.1 用户变量

shell允许把值存在变量中,shell变量名以字母或下划线字符开始,由字母、数字或下划线组成。要把值存入变量,只要写出变量名,或紧跟一个=,再加变量值即可。例如:variable=value    count=1在程序中使用变量的值时,要在变量名前面加上一个符号“$”。例如:echo $variable(echo的意思是打印后面的变量)

1.2 环境变量

环境变量是一种特殊的变量,可以由其他程序传递给脚本,在脚本中被调用的任何程序都将继承环境变量。可以像定义一个变量一样来设置环境变量,在标记它为环境变量时需要使用“export”命令:   export MYENV=1   echo $MYENV使用set命令可以获取当前上下文中全部的环境变量,使用env命令可以查看系统中全部环境变量

1.3 位置变量

由出现命令行上的位置确定的参数称做位置参数。总共有十个位置参数,其对应的名称依次是$0,$1,$2,…$9,其中$0表示命令名或Shell脚本名,不可或缺,其它位置参数可有可无。编辑ison脚本文件内容如下:   who | grep $1执行:chmod + x ison   ./ison bc

shell将用bc取代$1,命令行变为   who | grep $bc

1.4 预定义变量

$#变量用于存放命令行中所键入的参数个数$*变量可以引用传递给程序的所有参数其中shift命令的作用是把位置参数左移,原来$1中的值丢失,参数变量的个数自动减1

$@变量和$*变量功能基本相同

$?变量: 每当程序执行完成后都会给系统返回一个退出状态。该状态是个数值,通常指示该命令运行是否成功。退出状态为0表示运行成功,非零表示运行失败。shell自动将最后所执行命令的退出状态设置到shell变量$?中,可以用echo命令在终端上显示它的值。

2. shell特殊字符与表达式

2.1 三种通配符

  1. *星号,它匹配任意字符的0次或多次出现。但注意,文件名前面的圆点(.)和路径名中的斜线(/)必须显式匹配。
  2. ?问号,匹配任意一个字符
  3. []一对方括号,其中有一个字符组。其作用是匹配该字符组所限定的任意一个字符。注意*和?在方括号内,就不是通配符了。!叹号,若它紧跟在一对方括号的左方括号[之后,则表示不在一对方括号中所列出的字符。

2.2 引号与反斜线

  1. 双引号""括起来的字符,除$、倒引号和反斜线(\\)仍保留其功能外,其余字符通常作为普通字符对待。
  2. 单引号\’\’括起来的字符都作为普通字符出现。
  3. 倒(反)引号“用于设置系统命令的输出到变量,反引号中的内容作为一个系统命令并执行。
  4. 反斜线\\为转义字符,若想在字符串中使用反斜线本身,则必须采用(\\\\)的形式。

2.3 表达式

  1. 逻辑表达式:   && : 与   || : 或   ! : 非(需要有空格)
  2. expr求值表达式expr命令一般用于整数值,但也可用于字符串。一般格式为:expr argument operator argument 其中operator为 + – * / %,但对*的使用要用转义符\\。示例如下:   v1=3   v2=2   v3=`expr $v1 * $v2 `   echo $v3结果输出6

3. shell条件判断

3.1 if表达式

下面是if表达式的一般结构if   command1then   …elif  command2then   …else   …ficommand1和command2需要执行并检测其退出状态,如果退出状态为0(command为真),则执行其后的then语句,否则就跳到else或者elif或fi。下面是if用法的示例:其中:int1 –gt int2表示int1 大于int2int1 –lt int2表示int1 小于int2

3.2 case表达式

case用法结构如下:case string in   string1 )      …;;   string2 )      …;;   * )      …;;esac字符串string首先与string1和string2比较,如果匹配就执行它们下面的语句直到双分号。如果都不匹配,则执行* )下面的语句。下面是case用法的示例:

4. shell循环

4.1 for循环

for循环分为带列表和不带列表的。带列表将一组命令循环执行预先确定的次数,基本方法如下:不带列表的形式,shell会自动将命令行键入的所有参数依次组织成列表。

4.2 while循环

while循环示例如下:break命令与continue命令与C中相应命令功能相同。

5. shell函数

和“真正的”编程语言一样,shell也有函数,虽然在某些实现方面稍有些限制。函数被调用或被触发,只需要简单地使用函数名即可。函数示例如下:

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » make和shell入门