linux操作系统基础(含C编译,make编译,shell脚本)


Linux终端快捷键

快捷键含义
Tab输入一部分命令按可以自动补齐
Ctrl+shift+ +终端文字放大
Ctrl + -终端文字缩小
Ctrl+L清屏

一、文件管理

一些通用符号含义

./当前目录(不打点也是当前目录,如cd ./a和cd a)
../上一级目录(相对路径)
/根目录(绝对路径)
*所有文件(用于删除、复制、移动等)
-l详细信息(显示目录等)

文件操作常用命令

命令含义含义
clear清屏
pwd显示当前所在路径
ls查看当前文件夹目录
ls -a查看所有文件,包括隐藏文件
ls /查看根目录内容
ls -l /查看根目录详细信息
ls -l查看目录详细信息
在这里插入图片描述ls -l查看的信息中,第一个字母含义:- 普通文件 d 文件夹,b 设备文件(块设备) c设备文件(字符设备) i连接文件 s 套接字文件 p 管道文件
cd跳转目录
cd ~当前用户目录
cd a/b跳转到当前目录里a目录下的b目录
cd /根目录
cd -上一次访问的目录
cd ..上一级目录
touch创建文件
touch 路径和名字创建文件
touch test当前目录创建test文件
touch test/a在该目录下的test目录下创建a文件
touch test/a b在当前文件的test文件夹下创建a文件,当前文件下创建b文件
mkdir创建文件夹
mkdir aaa在当前目录下创建aaa目录,相对路径
mkdir -v aaa
mkdir ./bbb在当前目录下创建bbb目录,相对路径
mkdir /ccc在根目录下创建ccc目录,绝对路径
mkdir -p /home/a/b在home下创a,a下创b(需要加-p)
mkdir test/{a,b}在当前母的的test文件夹创建a,b文件夹
mkdir -pv test/{a/{b,c},d}在test下创a,d,在a下创b,c
cp复制
cp /home/a/b/c /home/a/复制文件
cp -r /home/a/b/c /home/a/复制文件夹(文件夹需要加-r)
c -r /home/a/b/* /home/a/复制b下的所有文件到a
MV移动
MV a/b/c aa中的b中的c移动到a中去
MV a/b/c a/da中的b中的c移动到a中去并改名为d(前提是a中没有d文件夹,有d文件这则移动到a中的d文件夹内)
MV a/b a/c将a中的b改名为c(前提是a中没有c)
rm删除
rm -rf a/*删除文件a内的所有文件夹和文件
rm -rf a/b*删除文件a内的所有b开头的文件夹和文件
rm -rf a/*b删除文件a内的所有b结尾的文件夹和文件
rm -rf a/a a/b删除a里面的a和b
rm -rf bbb强制删除当前目录下的bbb目录
rm -r bbb询问是否删除bbb目录
rm -rf a.java强制删除当前目录下的a.java文件
find查找文件
find -name a查看a文件夹
find -name a*查看a开头的文件或文件夹
find deirectory -name a指定目录中查找
cat查看文件内容(重点)
cat a.txt查看a.txt文件
more查看文件内容(翻页)
more a.txt查看a文件(按回车键一行一行进行查看, 按空格键一页一页进行查看,q退出)
tail查看文件后几行
tail -f a.java查看文件后10行内容
tail -n 5 a.java查看后5行内容
head查看文件前几行
head a.java查看文件前10行内容
head -n 5 a.java查看前5行内容
grep过滤,查找内容-i忽略大小写,-n标出显示行的列数
grep c a.txt查看文件a.txt内的包含c的内容
grep -nr “Ubuntu” /在整个系统里面查找Ubuntu(包括文件内)
> 文件名覆盖写入文件ls > a.txt 将查询的结果写入a.txt中
>> 文件名追加写入文件
ls > a.txt将查询目录的结果写入a.txt中(>前面的内容一定是正常的指令,可有输出的)
geidt文本编辑器
gedit a.txt编辑a.txt
du文件夹大小(-h人类可读的方式显示)du -h --max-depth=1(只显示一级目录文件大小)
df列出文件系统的整体磁盘使用量(包含大小,已用,可用等数据)
|管道(将管道左边命令的输出结果作为管道右边命令的输入)ls -l | more 将显示的内容分屏

二、其他指令

命令含义含义
uname查看系统信息(加-a详细信息)
sudo切换用户身份,提权
su切换用户
ifconfig显示网络配置信息
ifconfig 网卡名 down关闭网卡
ifconfig 网卡名 hw enter 00:AA:BB:CC:DD:EE修改MAC地址
ifconfig 网卡名 up启动网卡
ifconfig 网卡名:ws arp启动ARP
ifconfig 网卡名:ws -arp关闭ARP
ifconfig 网卡名 mtu 1500设置最大传输单元
reboot重启
poweroff关机
man系统帮助
man printf查看printf含义
sync数据同步写入磁盘
df磁盘空间检查
ps当前系统进程查看命令-aux显示所有行程,-au显示较详细咨询
top进程实时运行状态
file文件类型查看
echo输出内容echo $PATH输出路径

三、Ubuntu文件结构

在这里插入图片描述

文件路径含义
/bin存放二进制可执行文件,这些指令在单用户模式下也能够使用,可以被root和一般的账号使用
/bootUbuntu 内核和启动文件,比如 vmlinuz-xxx。gurb.引导装载程序
/dev设备驱动文件(ls sd*可以查看U盘,从这进行装载)
/etc存放一些系统配置文件,比如用户账号和密码文件,各种服务的起始地址
/home系统默认的用户主文件夹,一般创建用户账户的时候,默认的用户主文件夹都会放到此目录下
/lib存放库文件
/media此目录下放置可插拔设备,比如 SD 卡,或者 U 盘就是挂载到这个目录中
/mnt用户可使用的挂载点,如果要挂载一些额外的设备,那么就可以挂载到此处
/opt可选的文件和程序存放目录,给第三方软件放置的目录
/rootroot 用户目录,也就是系统管理员目录。
/sbin和/bin 类似,也是存放一些二进制可执行文件。sbin下面的一般是系统开机过程中所需要的命令。
/srv服务相关目录。比如网络服务
/sys记录内核信息,虚拟文件系统
/tmp临时目录
/var存放一些变化的文件,比如日志文件
/usrusr 不是 user 的缩写,而是 UNIXSoftware Resource 的缩写,存放于系统用户有关的文件,会占用很大的存储空间!“
/proc虚拟文件系统,数据放置到内存中,存放系统运行信息

四、用户基本信息

指令作用
cat显示文件内容
cat /etc/passwd查看用户基本信息
cat /etc/shadow查看用户密码信息
cat /etc/group查看组信息
cat user01 /etc/passwd查看user01用户基本信息
ls /home/查看用户,创建了user01就有user01文件
id user01用户user01存在则显示详细信息,不存在则提示没有
ls /var/spool/mail/user01用户邮件
whoami查看当前账户
grep hr /etc/group查看组名包含hr的信息

用户基本信息文件:cat /etc/passwd,被冒号分成七列,同户名:x:uid:gid:描述:HOME:shell,每一行是一个用户信息
在这里插入图片描述

列数含义
x密码占位符
uid用户的身份证号(系统约定:RHEL7,uid:0特权用户,uid:1~499系统用户,uid:1000+普通用户)
gid组号
描述解释
HOME家目录,登入系统时,所在的目录
shell登入shell,命令解释器

用户密码信息(经过了加密)文件:cat /etc/shadow,被冒号分成九列,最后一列没意义

在这里插入图片描述

列数意义含义
1用户名
2密码加密值*表示被锁定,双汉号表示密码过期,$6$开头表示用SHA-512加密,$1$用MD5解密,$2$用Blowfish加密,$5$用SHA-256加密
3最后一次修改时间从某个时间至今天数
4最小间隔3表示过3天可改密码
5最大时间间隔密码有效期
6警告时间提示还有多久密码过期了
7不活动时间用户不登入系统天数,超过时间没登入则禁用
8失效时间账户的有效期,到了失效时间账户失效
9保留什么意思都没有

组信息文件:cat /etc/group,被冒号分成四列,root: x:0:组名:组密码:组ID:组成员

在这里插入图片描述

4.1 用户管理

图形化创建要安装:sudo apt-get install gnome-system-tools(这里不介绍图像化操作)

用户在这个组,可以访问这个组内信息文件,可以共用空间,但不能访问其它组内信息文件(不在此组)。每个用户可以属于多个不同的组

#开头是超管用户(root用户),才可以创建用户等操作,$为普通用户没创建用户等操作能力
在这里插入图片描述

用户

指令作用
finger user01用户查询
useradd user01创建user01用户(-u指定组,-d /user01指定家目录为user01,)
adduser user01创建user01用户(设置密码等信息)
passwd修改当前账户密码(普通用户只能修改自己的,超管可以改其他账户)
passwd user01修改user01用户密码(密文输入,输入看不到,无显示)
userdel -r user01删除用户user01(不加-r删除后还保存文件)
usermod -s /sbin/nologin user01修改用户属性,用户不能登入
usermod -s /bin/bash user01修改用户属性,用户可以登入


一个用户有一个基本组(随用户而创建,一般组名用用户名),可以有多个额外加入的组为附加组(用户额外加入的组)

指令作用
groups user01查看user01用户在哪些组里面(显示格式:用户:组名
usermod -g user01 group01修改user01的基本组
usermod -G group01 user01修改user01的附加组(加-a添加不替换
usermod -a -G group01 user01给用户user01添加group01组
groupadd hr创造hr组(创建成功提示var/spool/mail/root中有邮件)(-u指定用户UID,-g指定用户的基本组,-G指定用户的附加组)
groupdel hr删除组
gpasswd -d A GROUP把用户A从GROUP组内移除
groupmod -g 1001修改组ID
su - root提权(进入root后exit退出root账户)(像root一样使用命令,但不是root)
sudo useradd user01提权(在普通用户下加个sudo才可以拥有root的权限执行命令,否则不能)
# 举例
用户AA,基本组1508,附加组空
用户BB,基本组1509,附加组空
组CC,组号1510,和谁都没关系
usermod AA -g CC
执行上述指令后,用户AA,基本组1510,附加组空
usermod BB -G CC
执行上述指令后,用户BB,基本组1509,附加组1510
CC组有两个成员,一个AA,一个BB

案例
先创建个用户user01,user02
adduser user01,adduser user02
cat /etc/passwd
在这里插入图片描述
创建用户后会自动生成两个组,指令格式:groups 用户名,显示格式:用户名:组名
在这里插入图片描述

再创建个用户组group01,group02,此时里面都没有用户
addgroup group01,addgroup group02
cat /etc/group
在这里插入图片描述
将用户user01从user01组移动到group01组,显示格式:用户名:组名
在这里插入图片描述
给用户user01添加个附加组,如果没有则添加,如果有则替换(加-a参数则是添加,不是替换,即usermod -a -G group01 user01)(刚开始没有附加组,直接添加,后来有附加组,没加-a参数,则替换,后来加了-a参数,再添加个附加组)
在这里插入图片描述
将用户user01从group02中移除
在这里插入图片描述
使用指令sudo deluser user01删除用户user01
使用指令sudo delgroup group01删除用户组group01

五、文件所属与权限

5.1 文件权限

文件状态:r为可读(r=4),w为可写(w=2),x为可执行(x=1)
可执行文件在命令行中运行./文件名就可以运行,比如,编写一个hello.c文件,运行gcc hello.c -o hello就会生成一个可执行文件,然后运行./hello即可运行)
在这里插入图片描述

在这里插入图片描述

使用ll查看文件,可以在左边看到文件的权限,左边方框内有10列,第一列表示文件类型,后面分为三个三组,第一组(2-4)用户权限,第二组(5-7)用户组内成员权限,第三组(8-10)其他用户权限
比如某文件显示如下 - rw- rw- r--:表示当前用户可读写无可执行,组内其他用户可读写无可执行,其他用户可读无可执行
在这里插入图片描述

上面方框后面数字后的两个a,第一个表示a用户,第二个表示a用户组
文件权限修改
可以用二进制形式修改文件权限,可读为4(100),可写为2(010),可执行为1(001)
指令格式:chmod 参数 文件名
比如我们将b.txt权限改为可读可写可执行,则运行chmod 777 b.txt指令,如下图
在这里插入图片描述

也可以用字母形式修改权限

字母含义
r可读权限
w可写权限
x可执行权限
a所有用户
u归属用户
g归属组
o其他用户
=具备权限
+添加权限
-移除权限

格式:chmod u/g/o/a+/-/=rwx
一定要注意格式顺序,先用户群体,再添加或删除,最后权限
比如我们将a.txt文件禁止组内其他用户编写,组内其他用户则是g(第二组),写为w,移除为-,则组合就是chomd g-w a.txt
在这里插入图片描述

5.2 修改文件所属用户

比如我们将a用户下的a.txt改到root用户当中sudo chown root a.txt
在这里插入图片描述

将a.txt的用户组有a改为root用户组sudo chown .root a.txt
在这里插入图片描述
同时修改a.txt属与a用户和a用户组sudo chown a.a a.txt
在这里插入图片描述
如果要将某文件内所有文件修改所属用户与用户组,则执行如下指令sudo chown -R 用户.用户组 文件夹名

六、软件安装

1、在应用商店下载

2、使用指令安装(apt工具):
sudo apt-get install 包名,如:sudo apt-get install git,再如sudo apt-get install mplayer(视频播放工具)

3、使用deb安装
首先在某网站官网下好安装包,即deb文件,相当于Windows下的exe,然后执行上面指令(在windows下,安装的是.exe文件,在Ubuntu中,安装的是.deb文件)
然后执行下面指令使用deb安装:sudo dpkg -i xxx.deb(卸载:sudo dpkg -r xxx
桌面上没有图标,我们在usr/share/applications目录下可以看到应用程序的桌面图标

4、自己下载源码编译
以tree为例,在网址下载:mama.indstate.edu/user/ice/tree
在这里插入图片描述
下载之后,该文件里面有操作步骤文档(install文件)
在这里插入图片描述

终端进入该文件夹
在这里插入图片描述首先执行make,然后执行sudo make install下载完成
(执行不带sudo会提示permission没权限,需要嗲sudo)
(ubuntu里面要拥有make,gcc工具,没有则要下载)
安装好了之后,可以运行tree查看
在这里插入图片描述

七、磁盘管理(U盘)

/dev/sd*文件,此类文件是磁盘设备文件,并不能直接访问磁盘,必须要将磁盘挂载到某一个目录下才可以访问

插上U盘后,可以在dev中查看U盘,在插U盘前后分别查看cd /dev,ls sd*,如下图可以看到有sdb和sdb1,sdb表示U盘,sdb1表示U盘的第一个分区
在这里插入图片描述
注:U盘要用FAT32格式的(在右击属性中可以查看),linux大部分系统都不支持NDFS格式的U盘
在这里插入图片描述
U盘挂载与卸载

插上U盘后,如果没有默认挂载,可以查看到文件,但是cd进不去(如上cd sdb1),需要挂载之后才可以进去,这种情况下需要我们手动挂载

先在/media/a里面创建一个udisk用于挂载U盘
在这里插入图片描述
然后执行sudo mount -o iocharset=utf8 /dev/sdb1 /media/a/udisk进行U盘挂载,挂载成功后,media/a/udisk里面就有U盘的内容(-o iocharset=utf8防止中文乱码)
在这里插入图片描述

执行sudo umount /media/a/udisk进行U盘卸载,后面是磁盘路劲,卸载后,此处就没有U盘内容
在这里插入图片描述
磁盘分区格式化
显示磁盘分区:sudo fdisk -l
sudo fdisk /dev/sdb,然后输入m获取帮助,然后按提示可以创建分区、删除分区(U盘处于挂载状态无法删除)等操作,操作完成之后输入w进行保存

使用sudo mkfs -t vfat /dev/sdb1进行格式化

八、压缩与解压

linux下常用的压缩格式有.tar,.tar.bz2,.tar.gz。因为linux下很多文件是.bz2,.gz的压缩文件,因此需要在windows下安装7.ZIP软件

指令含义
gzip压缩工具负责压缩和解压缩.gz格式的压缩包
gzip xxx压缩文件(压缩后原文件没了
gzip -d xxx.gz解压缩
gzip -r xxx压缩文件夹(批量对文件夹里的文件压缩,并不是将这个文件夹打包压缩成一个
gzip -rd xxx.gz解压文件夹
在这里插入图片描述
bzip2和gzip类似(效果一样),只负责压缩和解压bz2格式文件
bzip2 -z xxx压缩文件(压缩后原文件没了
bzip2 -d xxx.gz解压
在这里插入图片描述
tar提供打包服务,多个文件打包成一个(-c打包,-x提取,-j使用bzip2压缩格式,-z使用gzip格式,-v打印压缩过程)
tar -vcf a.tar a将文件夹a打包成a.tar
tar -vxf a.tar解压
tar -vxjf xxx.bz2解压
tar -vcjf xxx.bz2 xxx压缩
tar -vxzf xxx.tar.gz解压
tar -vczf xxx.tzr.gz xxx压缩
rar安装:sudo apt-get install rar
rar x xxx.rar解压缩(加x参数)
rar a xxx.rar x压缩(加参数a)
zipzip格式(-r文件夹压缩,-v显示过程)
zip -rv xxx.zip zip压缩
unzip xxx.zip解压

九、连接文件(硬连接、软连接)

连接方式分为符号连接(软连接)和硬连接,符号连接类似于Windows下的快捷方式,硬连接通过文件系统的inode连接来产生新的文件名,而不是产生新文件。
inode:记录文件属性,一个文件一个inode。inode相当于文件ID,查找文件的时候要先找到inode,然后才能读取文件内容

ln命令
ln命令用户创建链接文件
命令格式:ln [选项] 源文件 目标文件
选项:-s创建符号连接(软连接)
-f强制创建链接文件,如果目标存在,那么先删除目标文件,然后再建立文件
硬连接
硬连接是多个文件都指向同一个 inode,硬连接知识点:
1、具有相同inode 的多个文件互为硬连接文件,创建硬连接相当于文件实体多了入口
2、对于硬连接文件,只有删除了源文件以及对应的所有硬连接文件,文件实体才会被删除
3、根据硬链接文件的特点,我们可以通过给文件创建硬连接的方式来防止文件误删除
4、不论修改源文件还是连接文件,另一个文件的数据都会被改变。
5、硬连接不能跨文件系统。
6、硬连接不能连接到目录

举例
原先只有一个hello可执行文件,利用ln hello hello1ln hello hello2建立两个硬连接(ll -i查看inode),运行./hello./hello1./hello2都可以运行
在这里插入图片描述
此时我们将源文件hello删除,./hello1./hello2通用可以正常运行,删除原文件对其毫无影响,如果要删除,需要把连接和原文件都删除,即hellohello1hello2
在这里插入图片描述
再如,我们对hello.c建立连接,查看内容是一样的
在这里插入图片描述
我们对hello.c进行修改保存,可以发现hello1.c也跟着发生了变化
在这里插入图片描述
在这里插入图片描述

符号连接(软连接)
符号连接类似Windows 下的快捷方式,符号链接也叫做软连接,软连接要用的多。符号连接相当于创建了一个独立的文件,这个文件会让数据读取指向它连接的哪个文件的文件名。软连接的特点:

1、可以连接到目录。
2、可以跨文件系统。
3、删除源文件以后,软连接文件也就打不开了。
4、符号连接文件通过->来指示具体的连接文件。
5、符号连接要使用绝对路径,否则连接可能会出问题(拷贝cp(-d保留连接))

举例
我们用相对路径(容易出问题)和绝对路径分别举例,先建立连接,可以看到建立的链接文件比hello小很多
在这里插入图片描述

现在三个文件都可以正常运行,可以看到暂时没什么问题
在这里插入图片描述
当我们进行复制的时候,会出现问题,相对路径的就不能运行
在这里插入图片描述
当删除源文件的时候,可以发现建立的连接无法使用了
在这里插入图片描述

十、vim文本编辑器

安装:sudo apt-get install vim

vim文本编辑器
vim a.txt编辑a.txt(进入一般模式),进入后按ia才可以编辑文件,进入编辑模式后要退出先按esc,然后输入:和字母,比如:wq表示保存退出,:q!不保存退出。,:set nu设置行号,:set list显示控制字符,:set nonu取消设置行号,:w只保存不退出,:1,5 s/333/666/g一到五行的333换成,:w /tmp/a.txt另存为tmp下的a.txt
vim只进入,没有进入编辑,一些字母含义,yy复制(前面可以先按数字),p粘贴,d删除,u后退一步(撤销),v可视化(等于鼠标选择,选择后按Y可以复制),0行首,$行尾,G最后一行,gg第一行,6G第六行,/adm查找adm(enter查找,n跳转下一个,N上一个)
临时文件:vim未正常关闭产生的文件(如vim编辑a.txt未正常关闭产生.a.txt.swap),再次编辑是报错解决方案:查看影藏文件:ls -a,删除临文件

十一、C编程

vim默认TAB键为8空格,需要将其改为4空格,在/etc/vim/vimrc文件添加set ts=4(需要加sudo),添加set nu显示行号
在这里插入图片描述
使用vim helo.c编写一个hello.c文件,内容如下
在这里插入图片描述

使用指令gcc hello.c -o hello(或者分两步,gcc -c hello.c生成hello.o文件,执行gcc hello.o -o hello链接成hello可执行文件)编译C程序,编译结束之后会生成一个hello可执行文件,运行./hello即可运行(-o指定输出文件名,-v显示编译过程)
在这里插入图片描述
如果程序有误,使用gcc编译会报错,比如将hello.c修改缺少一个冒号,如下
在这里插入图片描述
此时使用gcc编译会报错
在这里插入图片描述

十二、make工具和makefile

当源码文件比较多的时候就不适合通过直接输入gcc命令来编译,这时候就需要一个自动化的编译工具。

make工具可以完成自动编译工作,如果修改了几个源文件,则侧重编译这几个修改的源文件;如果某个头文件修改了,则从新编译所有包含该头文件的源文件。make一般用于将源代码文件编译为可执行的二进制文件。make 工具编译的时候需要 Makefile 文件提供编译文件。

Makefile是make 工具所使用的文件,Makefile 指明了编译规则
makefile规则

目标...: 依赖文件集合...
	命令1
	命令2
	...

比如下面这条规则:

main: main.o  input.o  calcu.o
	gcc -o main main.o input.o calcu.o

这条规则的目标是main,main.o、input.o和calcu.o是生成main的依赖文件,如果要更新目标main,就必须要先更新它的所有依赖文件,如果依赖文件任何一个有更新,那么目标也必须更新,更新就是执行一遍规则中的命令列表(命令列表中的每条命令必须以TAB键开始,不能使用空格

make命令会为makefile中的每个以TAB开始的命令创建一个shell进程去执行

完整的指令:如下要生成main,需要依赖main.o,input.o,calcu.o,如果都存在,则执行命令gcc -o main main.o input.o calcu.o生成main,如果某个更新的依赖没有,则从下面找哪个指令生成的目标是这个依赖,然后执行生成依赖

main:	main.o 	input.o 	calcu.o
	gcc	-o	main	main.o	input.o	calcu.o
main.o:	main.c
	gcc	-c	main.c
imput.o:	input.c
	gcc	-c	input.c
calcu.o:	calcu.c
	gcc	-c	calcu.c

clean:
	rm	*.o
	rm	main

举例
首先创建文件main.c,内容如下:

#include<stdio.h>
#include "input.h"
#include "calcu.h"

int main(int argc, char *argv[])
{
	int a, b, num;
	input_int(&a, &b);
	num = calcu(a, b);
	printf("%d + %d = %d\r\n", a, b, num);
	return 0;
}

再创建文件input.c,内容如下:

#include<stdio.h>
#include "input.h"

void input_int(int *a, int *b)
{
	printf("input tow num:");
	scanf("%d %d", a, b);
	printf("\r\n");
}

再创建文件calcu.c,内容如下:

#include<stdio.h>

int calcu(int a, int b)
{
	return (a + b);
}

创建头文件input.h内容如下:

#ifndef __INPUT_H
#define __INPUT_H

void input_int(int *a, int *b);
#endif

创建头文件calcu.h文件如下:

#ifndef __CALCU_H
#define __CALCU_H

void calcu(int a, int b);
#endif

总共5个文件
在这里插入图片描述

如果我们用gcc编译,则需要将所有的.c文件都输入,即指令为:gcc main.c calcu.c input.c -o main生成可执行文件,然后./main运行程序
在这里插入图片描述这里使用gcc编译需要输入所有的.c文件,且会全部重新编译,耗时费力不方便。使用make可以方便很多,make只会对修改过的文件进行编译,不会全局编译,这里我们编写Makefile文件
在这里插入图片描述

编写完之后,然后执行make指令编译,会生成对应的.o文件和可执行文件,运行./main即可执行
在这里插入图片描述

如果要清除那些.o文件和可执行文件,运行make clean即可(上面makefile中编写了clean)
在这里插入图片描述
这里如果修改一个文件,从新执行make,就会对修改过的文件进行编译,不会执行未修改的文件

十三、Makefile基本语法

Makefile可以定义变量,如下面语句可以定义一个变量等于main.o input.o calcu.o,简化书写过程

main: main.o  input.o  calcu.o
	gcc -o main main.o input.o calcu.o

简化成如下

#Makefile变量使用
bojects	=	main.o  input.o  calcu.o
main:	$(objects)
	gcc	-o	main	$(objects)

=赋值,在原变量发送变化后,被该变量赋的值也会变化(如下面的curname)
在Makefile里面编写如下内容
在这里插入图片描述
运行make print得到如下结果(echo前面没加@输出了编译过程)
在这里插入图片描述
echo前面加个@,就不输出过程,只输出结果,没有命令这行
在这里插入图片描述

在这里插入图片描述
:=赋值,原变量发生变化,被赋值的变量不发送改变,curname等于原始的aa,不随name的改变而改变,而=赋值会跟着发送变化,代码如下
在这里插入图片描述
在这里插入图片描述
?=表示如果前面没有被赋值,则赋值该值,如果前面赋值了,则使用之前的值,比如name1先赋值为aa,然后?=bb,由于原先赋值了,这里就打印原先的值,name2没有赋值,则值为cc,代码如下:
在这里插入图片描述
在这里插入图片描述

+=追加内容,原先name内容为aa,后来使用+=符号追加bb,然后打印出来为aabb,代码如下:
在这里插入图片描述
在这里插入图片描述

main:	main.o 	input.o 	calcu.o
	gcc	-o	main	main.o	input.o	calcu.o
main.o:	main.c
	gcc	-c	main.c
imput.o:	input.c
	gcc	-c	input.c
calcu.o:	calcu.c
	gcc	-c	calcu.c

clean:
	rm	*.o
	rm	main

上面这个是一般规则,使用起来需要全部写上去,这里可以使用模式规则进行简化,在规则的目标定义中要包含%,%表示对文件名的匹配,%表示任意长度的字符串,比如%.c表示所有以.c结尾的文件,a.%.c表示所有以a.开头,以.c结尾的文件,目标中%所代表的值决定了依赖中的%值,上面的指令可以简化为如下(指令简化的gcc命令中运用到了自动化变量):

在这里插入图片描述

自动化变量描述
$@规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模式中定义的目标集合。
$%当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件,那么其值为空。
$<依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么“$<”就是符合模式的一系列的文件集合。
$?所有比目标新的依赖目标集合,以空格分开。
$^所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件“s^”会去除重复的依赖文件,值保留一份。
$+和“s^”类似,但是当依赖文件存在重复的话不会去除重复的依赖文件。
$*这个变量表示目标模式中"%"及其之前的部分,如果目标是 test/a.test.c,目标模式为 a.%.c,那么“$*”就是 test/a.test。

伪目标
当没有定义伪目标的时候,Makefile里面有如下内容
在这里插入图片描述
在外面运行make print就会有输出结果
在这里插入图片描述
如果在该文件夹里面存在print文件,则运行make print就不能正常使用
在这里插入图片描述

这是需要将Makefile里面对print使用伪目标(.PHONY:print),这时候就可以正常使用make print指令
在这里插入图片描述
在这里插入图片描述
条件关键字:ifeq,ifneq,ifdef,ifndef
ifeq和ifneq用来判断是否相等,ifeq用来判断是否相等,ifneq判断是否不相等(下面指令用来表示参数1与参数2是否会相同

ifeq	(<参数1>,	<参数2>)
ifeq	'<参数1>',	'<参数2>'
ifeq	"<参数1>",	"<参数2>"

ifdef和ifndef用法如下

ifndef<变量名>

如果变量名的值非空,则表达式为真,否则为假

Makefile函数使用
不支持我们自定义函数,使用方法如下

$(函数名	参数集合)

或者

${函数名	参数集合}

参数集合是函数的多个参数,参数之间用逗号隔开,函数名与参数之间用空格隔开,函数调用以$开头,常用函数如下

函数含义
subst字符串替换$(subst <from>,<to>,<text>)将text中的from内容替换为to,函数返回替换后的字符串
patsubst模式字符串替换$(patsubst <pattern>,<replacement>,<text>)查找text中的单词是否符合模式pattern,如果匹配就用replacement来替换,如$(patsubst %.c,%.o,a.c b.c c.c)将o,a.c b.c c.c中符合%.c的字符串替换为%.o
dir获取目录$(dir </src/a.c>)获取/src/a.c目录部分,也就是/src
notdir去除文件中的目录部分$(notdir </src/a.c>)获取/src/a.c非目录部分,也就是a.c
foreach完成循环$(foreach <var>,<list>,<text>)把list中的单词逐一取出放到var中,然后再执行text所包含的表达式,每次text都会返回一个字符串,循环过程中,text中所包含的每个字符串会以空格隔开
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值