linux1-4

终端:(虚拟终端) 所有输入输出设备总称

shell: 命令解析器

bash: bore again shell 命令解析器。

快捷键:

命令和路径补齐: tab
主键盘快捷键:
1).历史命令切换:
历史命令:history
向上遍历: ctrl + p
向下遍历: ctrl + n

2).光标移动:
向左: ctrl + b
向右: ctrl + f
移动到头部: ctrl + a
移动到尾部: ctrl + e

3).删除字符:
删除光标后边的字符: ctrl + d
删除光标前面的字符: ctrl + h
删除光标前面的所有内容: ctrl + u






/ 根目录
ls /

/bin 常用的命令

cd /bin 进入bin目录

/boot 开机启动项文件

/dev 设备文件

/etc 配置文件

/home 主目录,存放用户

/lib 动态链接库(共享库)

/lost-found 存放文件碎片

/media 挂载外设 U盘或光盘等等

/mnt 手动挂载外设到这个目录

/opt 第三方软件

/root 超级用户目录

/sbin 管理员使用的系统管理程序

/usr 用户软件资源目录(用户的软件或文件)

/usr/bin 系统用户的应用程序

/usr/sbin 超级用户使用的管理程序和系统守护程序

/usr/src 内核源码默认的放置目录



ctrl + l 清屏,或clear

cd 进入指定目录

绝对路径 从/开始
相对路径
./当前路径
…/上一级路径
cd - 两个相邻目录切换
cd ~ 切换到当前用户目录
cd 切换到用户目录

yxc19980620c@yc:~$

yxc19980620c 用户名
yc 主机名
~ 用户目录
$普通用户

超级用户root 切换到超级用户 sudo su 或 su root



-rw-r–r-- 1 root root 1937 9月 2 2020 ucontext.h

文件类型 所有者 所属组 其他人 硬连接数 文件所有者 文件所属组 文件大小 日期 文件名

文件类型
- 普通文件
d 目录
l 链接符号
b 块设备
c 字符设备
s socket文件
p 管道

ls和tree的使用:

ls -a 显示所有文件
ls -l 详细显示
ls -R 递归列出当前目录
ls -al
ls -h 人性化显示文件大小



tree 目录

pwd 查看当前位置



文件目录和文件的创建

mkdir 目录名
mkdir dri/dir/dir -p 递归创建目录
mkdir -p dir/dir/dir
touch 文件名
touch 文件名1 文件名2 … 文件名n



删除目录和文件

​ rmdir 空目录名
​ rm 目录名 -rf (f代表不提示)
​ rm 文件名 -f
​ rm 目录名 -ri (i代表提示)



文件和目录的拷贝

​ cp 源文件 目标文件名
​ cp h1 h2 将h1复制一份并命名为h2
​ 如果h2存在将原来内容覆盖
​ cp 源目录 目标目录 -r
​ 如果目标目录不存在就将源码目拷贝一份并命名为目标目录
​ 如果目标目录存在,就将源目录拷贝一份,复制到目的目录里面



查看文件内容

gedit 文件名

cat 文件名
cat 文件1 文件2 … 文件n 拼接查看文件
cat 文件1 | more

more 文件名
回车 一行
空格 一页
只能往后看
q 退出
ctrl + c 退出

less 文件名
回车 一行
空格 一页
可以往前后看
q 退出
ctrl + c 退出
ctrl + p 向前一行
ctrl + n 向后一行
ctrl +b 向前一页
ctrl + f 向后一下

head 文件名 显示文件前十行
head -5 文件名 显示文件前五行

tail 文件名 显示文件后十行
tail -5 文件名 显示文件后五行



mv命令

​ 文件改名

1
mv 源文件 改名后的文件

移动

1
mv 文件名 目录名    //将文件移动到目录中


ln 创建软链接

1
ln -s 源文件(绝对路径)  目标文件

​ 创建软链接最好使用绝对路径

ln 创建硬链接

1
ln 源文件(绝对路径)  目标文件

​ 只有文件才可以创建硬链接,不可以为目录创建硬链接
​ 硬链接是指向i(inode)节点的,在linux中所有文件都有一个i节点,i节点保存了一些文件信息
​ linux通过i节点找到文件的位置



文件的检索

1
2
3
4
	grep -r "文件内容" 路径    
-r代表递归检索文件
grep -r "printf" /
从根目录开始递归查找文件包含"printf"内容的文件


文件和目录属性命令

wc 获取文本文件的信息

1
2
yxsdc19c@yscc:/usr/include$ wc time.h
309 1515 10360 time.h

​ 309代表行数 1515代表单词个数 10360代表字节数



od 查看二进制文件

od -t 文件名
-t 指定数据的显示格式
-tc ASCII字符
-tx 十六进制数
-td 有符号十进制数
-tu 无符号十进制数
-to 八进制数
-tf 浮点数



查看某个目录的大小du

1
du -h 目录


查看磁盘的使用情况

1
df -h


查看命令在哪个目录 which

1
which 命令名

​ 内建命令是查不到的,例如cd,只能查外建命令



查看当前用户 whoami

1
whoami


修改文件权限

文字设定法: chmod [who] [+|-|=] [mode]

​ who:
​ 文件所有者: u
​ 文件所属组: g
​ 其他人: o
​ 所有的人: a

+:添加权限
-:减少权限
=:覆盖原来的权限

mode:
r:读 w:写 x:执行

1
2
3
chmod go-rw 文件名
chmod go+rw 文件名
chmod go=w 文件名

数字设定法

​ -:没有权限
​ r:4
​ w:2
​ x:1

765
7 – rwx --文件所有者
6 – rw --文件所属组
5 – rx --其他人

1
2
chmod 765 文件名
chmod -001 文件名 //减去其他人的执行权限


修改文件所有者和所属组

修改文件所有者

1
2
chown 用户名 文件名		//改变所有者
chown 用户名:所属组 文件名 //同时改变所有者和所属组

修改文件所属组

1
chgrp 所属组 文件名

目录必须拥有执行权限
如果目录没有执行权限x,会提示进不去的



文件的查找

按文件属性查找:

​ 文件名:

1
find 查找的目录 -name “文件的名字”

通配符:*代表所有字符 ? 代表一个字符

文件大小:

1
find 查找的目录  / -size +10k

· find 查找的目录 / -size -10k
· find 查找的目录 / -size -10M
find 查找的目录 / -size +10k -size -10M //表示大于10KB小于10MB的文件
+代表大于 - 代表小于
数字后面的字母区分大小写

文件类型:

find 查找的目录 -type 文件类型

1
2
find  / -type s
find / -type s


按文件内容查找

1
grep -r “查找内容” 查找路径

​ -r 代表递归查找



创建管道文件:

1
mkfifo 文件名


软件的安装和卸载

在线安装

​ apt-get
​ 安装

1
sudo apt-get install 软件名

​ 卸载

1
sudo apt-get remove  软件名

​ 更新

1
sudo apt-get update  更新软件列表

​ 软件列表存放的是软件名字和下载地址

清理所有软件安装包

1
sudo apt-get clean

实际清理的是: /var/cache/apt/archives目录下的.deb文件
aptitude
安装:

1
sudo aptitude install 软件名

重新安装:

1
sudo aptitude reinstall 软件名

更新:

1
sudo apt-get update

移除:

1
sudo aptitude rermove 软件名

显示状态:

1
sudo aptitude show 软件名

deb包安装

安装

1
sudo dpkg -i xxx.deb

卸载

1
sudo dpkg -r xxx

源码安装

1.解压缩源代码包
2.进入到安装目录
3. 检测文件是否缺失,创建Makefile,检测编译环境: ./configure
4.编译源码 生成库和可以执行程序:make
5.把库和可执行程序,安装到系统目录下: sudo make install
6.删除和卸载软件:sudo make distclean
7.上述安装步骤并不是绝对的,应该先查看附带的README文件



U盘挂载和卸载

卸载:

1
umount 设备文件名

挂载:

1
mount 设备文件名 挂载路径

自己在U盘目录里面是无法卸载的 ,就相当于不能在自己房间里才房间一样
将外设挂载到非mnt目录时,会临时覆盖原来内容,卸载之后会恢复

lsof命令

​ 用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。

1
2
lsof 参数 文件
lsof /mnt/

​ -a 列出打开文件存在的进程

-c<进程名> 列出指定进程所打开的文件

-g 列出GID号进程详情

-d<文件号> 列出占用该文件号的进程

+d<目录> 列出目录下被打开的文件

+D<目录> 递归列出目录下被打开的文件

-n<目录> 列出使用NFS的文件

-i<条件> 列出符合条件的进程。(4、6、协议、:端口、 @ip )

-p<进程号> 列出指定进程号所打开的文件

-u 列出UID号进程详情

-h 显示帮助信息

-v 显示版本信息



gzip

压缩出来的文件以.gz结尾
不保留源文件 不能对目录进行打包压缩

1
2
gzip 文件名
gzip *.txt

解压:

1
2
gunzip 文件名
gunzip *.gz


bzip2 — .bz2

​ -k 来保留源文件 不能对目录进行打包压缩

1
2
3
bzip2 文件名
bzip2 *.txt
bzip2 -k *.txt


tar

不使用z/j参数,该命令只能对文件或目录打包
c–创建—压缩
x–释放—解压缩
v–显示提示信息
f–指定压缩文件的名字

z–使用gzip的方式压缩文件
j–使用bzip2的方式压缩文件

压缩:

1
2
tar -zcvf 生成的压缩包的名字(xxx.tar.gz) 要压缩的文件或目录
tar -jcvf 生成的压缩包的名字(xxx.tar.bz2)要压缩的文件或目录

解压:

1
2
3
4
5
tar -zxvf 压缩包名字  //解压到当前目录
tar -jxvf 压缩包名字 //解压到当前目录
tar -zxvf 压缩包名字 -C(大写) 指定的目录
tar -zxvf xxx.tar.gz -C ./test
tar -jxvf xxx.tar.gz -C ./test


rar

​ 压缩:

1
2
rar a 压缩包的文件名 源文件
rar a bird *.c

​ 解压:

1
2
3
4
rar x 压缩包名 (解压到当前文件夹)
rar x 压缩包名 解压的路径
rar x bird.rar
rar x bird.rar ./


zip

​ 参数: 压缩目录要加参数 -r
​ 压缩:

1
2
zip 压缩包的名字 压缩的文件或目录
zip man *.txt

​ 解压缩:

1
2
unzip 压缩包的名字
unzip 压缩包的名字 -d 解压目录


ps 查看进程信息

​ 参数:
​ a 显示现行终端机下的所有程序,包括其他用户的程序。
​ u代表 以用户为主的格式来显示程序状况。
​ x 代表没有终端的程序

1
ps aux

| 管道

​ 将A输出作为B输入

1
ps aux | grep bash  //将ps输出的结果作为grep的输入,然后将结果显示回终端

kill

1
2
3
4
kill -l   //查看信号
kill -信号(可以只写数字) PID
kill -9 13442
kill -SIGKILL 123432


env和top

1
2
env查看环境变量
top 打开任务管理器

linux 环境变量:

​ 变量=值
​ 多个值用 : 隔开
​ PATH=A:B:C:D



ifconfig查看ip

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.44.135 netmask 255.255.255.0 broadcast 192.168.44.255
inet6 fe80::7438:27c1:6044:963d prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:f2:c7:2a txqueuelen 1000 (以太网)
RX packets 28453 bytes 18295064 (18.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10656 bytes 815687 (815.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (本地环回)
RX packets 945 bytes 84825 (84.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 945 bytes 84825 (84.8 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

ens33: 代表设备名 broadcast 广播地址 inet: ip地址



ping 命令

​ 检查网络是否通

1
2
3
4
5
ping ip地址
ping 192.168.1.123
ping ip地址 -c 次数 //ping多少次
ping ip地址 -i 秒数 //每隔多少秒返回一次结果
ping 域名


nslookup 把域名转换为ip

1
nslookup 域名


用户管理:

1
adduser 用户名

​ 创建一个用户
​ 需要管理员权限
​ 用户名不能有大写字母

1
sudo adduser abc

su

​ 切换用户

1
su 用户名

exit

​ 退出当前用户

useradd

​ 创建一个用户
​ 用户名可以大写
​ 需要管理员权限

1
useradd -s /bin/bash -g xiaoai -d /home/xiaoai -m xiaoai

​ -s 表示使用什么命令解析器
​ -g 用户组
​ -d 用户家目录
​ -m 如果用户家目录不存在,则创建一个目录

groupadd

​ 添加一个用户组
​ 需要管理员权限

1
groupadd 用户组名

passwd

​ 修改用户密码
​ 需要管理员权限

1
passwd 用户名

​ passwd 不加sudo 不输入用户名表示修改当前用户密码
​ sudo passwd 表示修改root用户密码

deluser

​ 删除用户

1
deluser 用户名

​ 需要手动删除家目录

userdel

​ 删除用户

1
userdel -r 用户名

​ 不需要手动删除家目录



查看当前系统下有哪些用户

1
2
vim /etc/passwd
yxc19980620c:x:1000:0:yc:/home/yxc19980620c:/bin/bash

​ /bin/bash 代表使用什么命令解析器



ftp服务器配置 vsftpd

作用:文件上传和下载

ftp服务器配置

​ 配置文件在/etc/vsftpd.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
anonymous_enable=YES  允许匿名用户登录

write_enable=YES 实名登录用户拥有写的权限

local_umask=022 设置本地掩码为022



anon_mkdir_write_enable=YES 匿名用户可以在ftp服务器上创建目录

listen_ipv6=NO

listen=YES

重启ftp服务

1
sudo service vsftpd restart

ftp服务

1
2
3
4
5
6
7
sudo service vsftpd start 启动ftp

sudo service vsftpd stop关闭ftp服务

sudo service vsftpd restart重启ftp服务。

service vsftpd status查看状态

实名登录ftp

1
2
3
ftp ip地址
输入用户
输入密码

退出

1
2
3
bye 
quit
exit

文件上传和下载

上传
在什么目录登录的,文件默认从那里找

1
put 文件名

下载

1
get 文件名

不允许操作目录,可以打包处理

匿名登录服务器

用户名 anonymous

密码是空
不允许匿名用户在任意目录直接切换
只能在一个指定的目录范围内工作
需要在ftp服务器上创建一个匿名用户的目录 --匿名用户的根目录



配置文件在/etc/vsftpd.conf
在配置文件添加 anon_root=/home/yxc19980620c/myFtp/
匿名登录默认路径是在/srv/ftp
在配置文件/etc/passwd可以查看并修改

1
ftp:x :123:127:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin


lftp客户端

1
sudo apt-get install lftp   	//下载

登录服务器:
匿名:

1
lftp 服务器ip

​ 输入login
​ 实名:

1
2
lftp 用户名@ip地址
输入服务器密码



1
2
3
4
5
6
7
8
9
10
11
lpwd 获取本地当前目录地址
pwd 获取服务器当前目录地址
lcd 目录 //切换本地目录
cd 目录 //切换服务器目录

put 文件名 //上传文件
mput 文件1 文件2 文件3 //上传多个文件
get 文件名 //下载文件
mget 文件1 文件2 文件3 //下载多个文件
mirror 目录名 //下载整个目录及其子目录
mirror -R 目录名 //上传整个目录及其子目录


nfs服务器

​ 安装

1
sudo apt-get install nfs-kernel-server

功能: 创建一个共享目录

1).先创建一个目录 mkdir 目录名

2).修改配置文件
/etc/exports
添加这一行 /home/用户名/共享目录 *(访问权限,sync)
/home/qwe/aa *(rw,sync)
*代表ip地址 访问权限有ro(只读),rw(可读可写),sync(代表实时更新)

ro 只读
rw 读写
root_squash 当NFS客户端以root管理员访问时,映射为NFS服务器的匿名用户
no_root_squash 当NFS客户端以root管理员访问时,映射为NFS服务器的root管理员
all_squash 无论NFS客户端使用什么账户访问,均映射为NFS服务器的匿名用户
sync 同时将数据写入到内存与硬盘中,保证不丢失数据
async 优先将数据保存到内存,然后再写入硬盘;这样效率更高,但可能会丢失数据

重启服务

1
sudo service nfs-kernel-server restart

客户端:

​ 挂载服务器共享目录

1
2
mount 服务器ip:共享目录   /mnt
mount 192.168.1.123:/home/xiaoh/nfs /mnt

aptitude 查看软件是否安装

1
2
安装 :sudo apt-get install aptitude
sudo aptitude show 软件名


ssh 远程登录到服务器

​ 安装:

1
sudo apt-get install openssh-server

​ 查看是否安装ssh

1
sudo aptitude show openssh-server

配置文件:/etc/ssh/ssh_config

远程登录:

1
2
3
ssh 用户名@ip
输入yes或no
输入密码

退出登录:

1
logout

scp命令

​ 超级复制
​ 使用该命令的前提条件是目标主机已经成功安装openssh-server

使用格式:

1
scp -r 目标用户名@目标主机ip地址:/目标文件的绝对路径 /保存到本机的绝对(相对)路径

​ 拷贝目录要加-r,拷贝文件不需要加-r

1
scp -r yxc19980620c@192.168.44.135:/home/yxc19980620c/test2 ./test3


终端翻页
Shift + PageDown 下翻页

清屏:
clear
Ctrl+l

创建终端:
Ctrl+Alt + T(Ubuntu)
Ctrl+Shift +T(添加新标签页)



看手册:

1
man [编号] 命令名

​ 编号:
​ 1 普通用户可以执行的系统命令和可执行文件的帮助
​ 2 内核可以调用的函数和工具的帮助
​ 3 C语言函数的帮助
​ 4 设备和特殊文件的帮助
​ 5 配置文件的帮助
​ 6 游戏的帮助(个人版的Linux中是有游戏的)
​ 7 杂项的帮助
​ 8 超级用户可以执行的系统命令的帮助
​ 9 内核的帮助



设置或查看别名

​ 查看

1
2
alias 命令名
alias ls

​ 设置

1
2
alias 新命令名='命令操作'
alias pag='ps aux | grep'

​ 需要长久有效需要去设置配置文件:.bashrc



echo
在显示器上显示数据
普通数据: echo 字符串
显示环境变量:

1
2
echo $变量名
echo $PATH

​ 显示上一次程序退出值:

1
echo $?

​ $代表取值



poweroff 关机

reboot 重启

shutdown
-a 指定权限
-r 重启计算器(和reboot)命令一样
-k 模拟关机(只向用户发出警告信息,但不关机)
-h 关闭计算机并关闭电源(常用)
-n 不调用init进程关闭计算机(不推荐)
-c 取消正在执行的关机命令
-f 重启计算机,但不进行磁盘检测
-F 重启计算机,进行磁盘检测
-t(秒) 指定发出警告信息与删除信息时要延迟的秒数

1
2
3
shutdown -r now 	//加now则是立即重启
shutdown -h +1 "1 minute after shutdown"
//设置1分钟以后关闭计算机,并在SSH中提示“1 minute after shutdown”

shutdown -c //取消关机
shutdown now //切换至单人操作模式



vi----vim

​ vim是从vi发展过来的一款文本编辑器

1
vi a.txt

前提安装了vim软件

工作模式:
命令模式:-- 打开文件之后,默认就是命令模式(ESC键)
编辑模式:–需要输入一些命令,切换到编辑模式(iaos,IAOS),按esc键回到命令模式
末行模式:-- 在末行模式可以输入一些命令( : 键 ) 按两次esc键切回命令模式
编辑模式不能直接切回到末行模式,需要先切换到命令模式,然后再切回到末行模式

命令模式下的操作:

光标移动:

​ H J K L
​ 前 下 上 后
​ 行首:0
​ 行尾:$
​ 文件开始位置:gg
​ 文件末尾:G
​ 行跳转:300g

删除操作:

​ 删除光标后边的字符:x
​ 删除光标前的字符:X
​ 删除单词:dw(光标移动到单词开始位置,否则只能删除一部分)
​ 删除光标到行首的字符串:d0
​ 删除光标到行尾字符串:D(d$)
​ 删除光标当前行:dd
​ 删除光标多行:ndd(n–自然数)

撤销操作:

​ 撤销:u
​ 反撤销:ctrl+r

复制粘贴:

​ 复制:yy
​ 复制多行:nyy

粘贴:p(光标所在行的下一行)
粘贴:P(大写,光标所在行)

在vim中剪切等于删除
剪切:dd(剪切一行)
剪切多行:ndd(n–自然数)

可视模式:

​ 切换到可视模式:v
​ 选择内容:h j k l
​ 复制:y 删除当前行:d
​ 粘贴:小写p(粘贴到光标下一个字符)或大写P(粘贴到光标上一个字符)

查找操作:
​ /查找内容 往下找
​ ?查找内容 往上找

把光标移动到查找的单词上,按#

​ 遍历快捷键:n或N,往下找n是下一个,N是是一个,往上找n是上一个,N是下一个,取决于查找方向

r:替换当前字符 按下r之后输入一个字符,只能替换一个字符

缩进:

​ 向右:>>
​ 向左:<<

查看帮助文档,首先光标移动到关键字或函数那里,然后按下数字,例如3,在按shitf+k

文本模式下的操作:

切换到文本模式:

​ a – 在光标所在位置的后边插入
​ A – 在当前行的尾部插入

i – 在光标所在位置的前边插入
I – 在光标所在行的行首插入

o – 在光标所在行的下边开辟一个新的行
O – 在光标所在行的上边开辟一个新的行

s – 删除光标后边的字符,然后插入
S – 删除光标所在行,然后插入

末行模式下的操作:

​ 替换:先查找,然后光标移动到要替换的行

1
2
3
4
5
6
:s/tom/jack 	代表用jack替换当前行的第一个tom
s/tom/jack/g 代表用jack替换当前行的所有tom
:%s/tom/jack 代表用jack替换当前文本所有行的第一个tom
:%s/tom/jack/g 代表用jack替换当前文本的所有tom
:20,25s/tom/jack/g 代表用jack替换20行到25行的tom
:20,25s/tom/jack/ 代表用jack替换20行到25行的第一个tom

保存退出:

​ :q 退出
​ :q! 退出不保存
​ :w 保存
​ :wq 保存退出
​ :x 保存退出

命令模式下的保存退出:ZZ

命令模式分屏操作:
:sp 将屏幕分成两部分 水平
:vsp 将屏幕分成两部分 垂直
:sp或vsp +文件名,水平或垂直拆分窗口显示两个不同的文件

:wqall保存并退出所有屏幕
:wall 保存所有
:wq保存并退出光标所在的屏幕
:q 退出当前屏幕
ctrl+ww 切换屏幕

vim打造IDE
系统级配置文件目录:/etc/vim/vimrc
用户级配置文件目录: ~/.vim/vimrc



编译过程:

源文件---->预处理—>编译—>汇编---->链接---->可执行文件

预处理器(.i)—>编译器(.s)---->汇编器(.o)---->链接器

hello.c—>hello.i----->hello.s-----hello.o----a.out

预处理器(cpp):头文件展开,宏替换,注释去掉

1
gcc -E hello.c -o hello.i

编译器(gcc):c文件编程汇编文件

1
gcc -S hello.i -o hello.s

汇编器(as):汇编文件变成二进制文件

1
gcc -c hello.s -o hello.o

链接器(ld):将函数库中相应的代码组合到目标文件中

1
gcc hello.o -o hello

直接生成可执行文件:

1
2
gcc hello.c -o myapp
gcc hello.c //生成一个默认的可执行文件 a.out

指定头文件目录

1
2
gcc hello.c -I ./include -o app
gcc hello.c -I./include -o app 旧版本的gcc -I后面不可以有空格

​ ./include就是头文件的目录

#ifdef DEBUG
printf(“123”)
#endif

通过gcc定义一个DEBUG宏

1
gcc hello.c -o app -D DEBUG

优化程序(-O大写)

优化等级 0~3,0不优化

1
gcc hello.c -o app —O3

输出警告信息(-Wall)

1
gcc hello.c -o app -Wall

添加调试信息(-g)

1
gcc hello.c -o app -g


静态库的制作和使用

命名规则:

1
2
lib + 库的名字 +.a
例如:libMylib.a

制作步骤:

​ 1)生成对应的.o文件

1
gcc *.c -c

2)将生成的.o文件打包

1
2
ar rcs 静态库的名字 生成的所有.o文件
ar rcs libMylib.a *.o

发布和使用静态库

​ 1)发布静态库
​ 2)头文件

使用:

1
2
3
4
5
gcc main.c 库的目录和名字 -o main
gcc main.c ./libMylib.a -o main

gcc main.c -L 库的目录 -l 库的名字(将lib和.a去掉) -o main
gcc main.c -L lib -l Mylib -o main

静态库的优缺点:

​ 优点:
​ 发布程序的时候不需要提供对应的库
​ 加载库的速度快

缺点;
库被打包到应用程序中,导致库的体积很大
库发生改变,需要重新编译程序

链接器是以.o为单位链接的

nm

1
nm 库的名字/可执行程序

可以查看库的一些信息
T 代表在代码区



共享库(动态库)

共享库的制作:

​ 命名规则:

1
lib+名字+.so

制作步骤:

​ 1)生成与位置无关的代码(生成与位置无关的.o)

1
gcc -fPIC -c *.c

​ 2)将.o打包成共享库(动态库)

1
gcc -shared -o libMylib.so *.o

共享库是程序运行的时候才加载的

发布和使用共享库(动态库)

​ 1)头文件
​ 2)库文件
​ 使用:

1
2
gcc main.c 库的目录和名字 -o main
gcc main.c ./libMylib.so -o main

解决程序执行时动态库无法被加载的问题

​ 1)将库文件放到/lib目录里(不建议使用)

2)临时设置终端环境变量
环境变量:LD_LIBRARY_PATH=将动态库的路径设置给该变量
将设置的值,导入到环境变量中:

1
2
export LD_LIBRARY_PATH=目录
export LD_LIBRARY_PATH=./lib

​ 终端关闭失效

3)设置家目录.bashrc配置文件
​ 在.bashrc文件最后一行添加

1
export LD_LIBRARY_PATH=目录(绝对路径)

​ 每次启动bash时都会自动执行这条命令
​ 终端重启生效

4)
​ 1.需要找动态链接器的配置文件

1
/etc/ld.so.conf

​ 2.动态库的路径写到配置文件
​ 3.更新

1
sudo ldconfig -v

动态库的优缺点:

​ 优点:
​ 1)执行程序体积小
​ 2)动态库更新了,不需要重新编译程序,前提是函数接口不变

缺点:
发布程序的时候,需要将动态库提供给用户
动态库没有被打包到应用程序中,加载速度相对较慢

gdb调试

可执行程序必须包含调试信息-g

1
2
gdb 程序名
gdb main
1
2
3
4
5
6
7
8
9
l  输出十行源代码

l 文件名:要查看第几行
l main.c 10

l 文件名:函数名
l main.c main

后面继续按回车可以继续显示源代码,直到输入了其他命令

设置断点

1
2
3
4
5
6
7
b 行号/函数名
break 行号/函数名

break 22
b 37
b main
break main

条件断点

1
2
b 行号 if 条件
b 15 if i==15 //当i等于15时,设置15行断点

查看断点信息

1
2
3
4
5
6
7
8
i b

info break

Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000006cf in main at main.c:6
enb y表示断点开始,n表示断点关闭
main.c:6 代表在main.c文件的第六行断点

删除断点

1
2
3
4
需要通过 info break 找到断点编号

d 编号
d 4
1
start 执行一步

单步调试

1
n

继续执行

1
2
c 
代表执行到断点的位置

进入函数内部

1
s

查看变量的值

1
2
p 变量名
p i

查看变量的类型

1
2
ptype 变量名
ptype i

追踪变量的值

1
2
3
4
5
6
7
8
display 变量名
display i

取消追踪变量
undisplay 追踪变量的编号
undisplay 1
查看追踪变量的编号
info display

跳出当次循环

1
u

跳出当前函数

1
finish

循环有断点需要先删除断点

设置变量的值

1
2
set var 变量名=值
set var i=10

退出gdb

1
quit

makefile

项目代码管理工具

1).命名规则

Makefile或makefile

2).makefile的规则:

规则中有三要素:目标,依赖,命令

1
2
make 
make命令运行makefile

image-20211228222234708

1
2
3
4
5
6
目标:依赖
命令 //命令左边一定要有一个tab缩进


app:main.c add.c sub.c mul.c
gcc main.c add.c sub.c mul.c -o app

image-20211229002343337

image-20211229002843041

1
2
3
4
5
6
7
8
main:main.o add.o		
gcc main.o add.o -o main

main.o:main.c
gcc -c main.c

add.o:add.c
gcc -c add.c

当add.c的修改时间 大于add.o的修改时间时,表示文件过时了

终极目标一定要在最前面

makefile中的变量

1
2
变量名=值
$(变量名) 代表取变量的值
1
2
3
4
5
6
7
obj=main.o add.o
target=main
$(target):$(obj)
gcc $(obj) -o $(target)

%.o:%.c
gcc -c $< -o $@
1
%.o:%.c代表自动匹配,当main.o找不到的时候,会自动匹配%.o:%.c,然后变成main.o:main.c

makefile中的自动变量

1
2
3
4
$< 规则中的第一个依赖
$@ 规则中的目标
$^ 规则中的所有依赖
只能在规则的命令中使用

由Makefile维护的一些变量

1
2
3
4
5
通常都是大写
CC:默认值cc
CPPFLAGS:预处理器需要的选项 -I
CFLAGS:编译的时候使用的参数 -Wall -g -c
LDFLAGS: 链接库使用的选项 -L -l
1
2
3
4
5
6
7
8
9
obj=main.o add.o
target=main
CC=gcc

$(target):$(obj)
$(CC) $(obj) -o $(target)

%.o:%.c
$(CC) -c $< -o $@