目录
- 知识点
- Linux系统目录:
- Linux系统文件类型: 7/8 种
- 文件权限说明
- gcc编译
- 动态库和静态库理论对比
- 系统调用和(库函数比较—预读入缓输出)
- 命令
- 创建软硬连接
- 软连接(快捷方式)
- 硬链接
- 用户创建、管理、删除
- 查找与检索
- find命令(直接搜索文件)
- grep(搜索文件内容形式查找)
- 安装和卸载软件
- 压缩、解压
- tar
- rar
- zip
- vim
- 三种工作模式
- 跳转、删除、复制、查找、分屏、命令
- gcc
- 静态库制作与使用
- 动态库的制作和使用
- gdb调试
- makefile
- 系统编程
- open、close函数
- 错误处理函数:与 errno 相关。
- read和write实现cp
知识点
/(系统的根目录)
~(当前用户的更目录,在/home里选择用户)
Linux系统目录:
bin:存放二进制可执行文件
boot:存放开机启动程序
dev:存放设备文件: 字符设备、块设备
home:存放普通用户
etc:用户信息和系统配置文件 passwd、group
lib:库文件:libc.so.6
root:管理员宿主目录(家目录)
usr:用户资源管理目录 unix software resource
Linux系统文件类型: 7/8 种
普通文件:-
目录文件:d
字符设备文件:c
块设备文件:b
软连接:l
管道文件:p
套接字:s
未知文件。
文件权限说明
目录项详细信息
文件权限 硬链接计数 所有者 所属组 大小 时间 文件名/文件夹名
权限具体展开
-rw-r—r—
1234567890
1代表文件类型
234代表所有者读写执行权限
567代表同组用户读写执行权限
890代表其他人读写执行权限
r(Read,读取):对文件而言,具有读取文件内容的权限;对目录来说,具有浏览目录的权限。
w(Write,写入):对文件而言,具有新增,修改,删除文件内容的权限;对目录来说,具有新建,删除,修改,移动目录内文件的权限。
x(eXecute,执行):对文件而言,具有执行文件的权限;对目录了来说该用户具有进入目录的权限。
gcc编译
gcc编译可执行程序4步骤:预处理、编译、汇编、链接
数据段合并
动态库和静态库理论对比
- 静态库在文件中静态展开,所以有多少文件就展开多少次,非常吃内存100M展开100次,就是1G,但是这样的好处就是静态加载的速度快
- 使用动态库会将动态库加载到内存,10个文件也只需要加载一次,然后这些文件用到库的时候临时去加载,速度慢一些,但是很省内存。
动态库和静态库各有优劣,根据实际情况合理选用即可。
系统调用和(库函数比较—预读入缓输出)
- 系统函数read、write没有用户级的缓冲区,在读写数据时需要用户自己定义一个buf数组用于缓冲数据,而读写的效率则取决于这个buf的大小
- 库函数fgetc、fputc有用户级缓冲区,不用指定一个数组来进行缓冲数据,在读写的时候是采取预读入缓输出的方式。
- 预读入:若用户每次只想读取一个数据,此时内核并不会每次从磁盘只读取一个数据然后给到用户,而是从磁盘预读入一些数据一个一个的交给用户
- 缓输出:在写数据的时候会将fputc的用户级缓冲区填满了再向内核输出。(图上标在内核不知道有没有问题)
命令
创建软硬连接
软连接(快捷方式)
为保证软连接可以任意搬移, 创建时务必对源文件使用 绝对路径。
ln -s file ~/28_linux/file.soft
硬链接
操作系统给每一个文件赋予唯一的 inode,当有相同inode的文件存在时,彼此同步。删除时,只将硬链接计数减一。减为0时,inode 被释放。
ln file file.hard
用户创建、管理、删除
创建、删除用户
sudo adduser 新用户名 #— useradd
sudo deluser 用户名
修改文件所属用户
sudo chown 新用户名 待修改文件
sudo chown wangwu a.c
可使用chown一次修改文件所有者和所属组
sudo chown 所有者:所属组 待操作文件
创建、删除用户组
sudo addgroup 新组名
sudo delgroup 用户组名
修改文件所属用户组
sudo chgrp 新用户组名 待修改文件
查找与检索
find命令(直接搜索文件)
find ./ -maxdepth 1 -typy 'l' #查找路径、查找深度 1表示在指定路径下查找、查找方式 type或者name或者size
-type l
按类型,还有d、p、s、c、b、l、f(普通文件)
-name ‘a.c’
按名字
-size +20M -50M
按大小查找大于20M小于50M的文件
-maxdepth (在其他参数前面)
指定查找深度
-atime、-mtme、-ctime、-amin、-mmin、-cmin
前三个含义:访问事件为几天内,修改属性为几天内,修改内容为几天内
-exec 将find的搜索结果集执行指定命令
find ./ -maxdepth 1 -type f -exec ls -ld {} \;
-ok 同exec但是在执行命令会询问用户,比如是否确定删除
-xargs 将find的搜索结果集执行指定命令,当结果集过大时,可以分片映射去查找速度更快,比-exec性能好
find ./ -maxdepth 1 -type f | xargs ls -ld
-print0 解决-xargs查找时文件名字有空格的问题(因为其分片时以空格分片)
find /usr/ -name '*tmp*' -print0 | xargs -0 ls -l
#第一个-print0指定结果集分隔为null,第二个-0指定xargs分隔为null这里不能用-print0
grep(搜索文件内容形式查找)
grep -r 'copy' ./ -n #-n显示行
ps aux | grep 'cupsd'
#查找线程名为‘cupsd’的,若存在该线程至少有两个结果,因为有一个线程是grep的
安装和卸载软件
1.联网
2.更新软件资源列表到本地 sudo apt-get update
3安装 sudo apt-get install 软件名
4.卸载 sudo apt-get remove 软件名
5.使用软件包(.deb)安装:sudo dpkg -i 安装包名
更换软件源:
系统设置->软件和更新->下载自…
换软件源过后要更新软件列表
软件包安装:
压缩、解压
tar
压缩:tar -zcvf 要生成的压缩包名 压缩材料(材料可有多个)
tar zcvf test.tar.gz test1 dir (gzip方式压缩)
tar jcvf test.tar.gz test1 dir (bzip2方式压缩)
解压:将命令中的c --> x
tar zxvf test.tar.gz (gzip方式解压缩)
tar jxvf test.tar.gz (bzip2方式解压缩)
gzip和bzip2都只能对当个文件进行压缩所以有了tar命令
rar
压缩:rar a -r 压缩包名(带上.rar后缀) 压缩材料
rar a -r testrar.rar stdio.h test.mp3 dir1
解压: unrar x 压缩包名
zip
压缩: zip -r 压缩包名(带.zip后缀) 压缩材料
zip -r testzip.zip dir1 stdio.h
解压:unzip 压缩包名(带.zip后缀)
unzip testzip.zip
vim
三种工作模式
i 进入编辑模式,光标前插入字符
a 进入编辑模式,光标后插入字符
o 进入编辑模式,光标所在行的下一行插入
I 进入编辑模式,光标所在行的行首插入
A 进入编辑模式,光标所在行的行末插入字符
O 进入编辑模式,光标所在行的上一行插入字符
跳转、删除、复制、查找、分屏、命令
- 跳转到指定行:
88G(命令模式)
88(末行模式) - 跳转到文件首:
gg(命令模式) - 跳转到文件尾:
G(命令模式) - 自动格式化程序:
gg=G - 光标跳转至行首:
0(命令模式)执行完工作模式不变 - 光标跳转至行尾:
$(命令模式)执行完工作模式不变 - 删除单个字符:
x(命令模式)执行完工作模式不变 - 替换单个字符:
将光标选择要替被换字符,按r(命令模式)输入替换的字符 - 删除一个单词:
dw(命令模式)光标要移到单词首字母 - 删除光标至行尾:
D(命令模式)或者d$(命令模式) - 删除光标至行首:
d0(命令模式) - 删除指定区域:
按v(命令模式),切换为可视模式,使用hjkl挪移光标来选择要删除区域,最后按d删除 - 删除指定n行:
光标在行首按ndd(命令模式),删除一行为dd - 复制n行、粘贴:
nyy复制,p向后粘贴,P向前粘贴(命令模式) - 查找:
1.命令模式下按/,输入想查找的内容按回车。使用n查找下一个
2.命令模式下,将光标置于单词任意一字符上按*(向后找)按#(向前找) - 替换:
– 单行替换 光标选在改行进入末行模式,输入:s /原数据/替换数据
– 通篇替换 末行模式,输入:%s /原数据/替换数据/g(不输入g会只替换一行的第一个出现的原数据)
– 指定行替换 末行模式,输入:起始行号,中止行号s /原数据/替换数据/g(不输入g会只替换一行的第一个出现的原数据)
29,35s /printf/println/g
- 撤销、反撤销:
u、ctrl+r(命令模式) - 分屏:
– 横屏分 末行模式输入:sp (命令模式ctrl+ww切换,ctrl按着不放)
– 竖屏分 末行模式输入:vsp - 跳转到man手册:
光标置于待查看函数单词上,按K(命令模式)跳转,跳转指定卷nK - 查看宏定义:
将光标置于查看宏定义的单词上,输入:[d查看(命令模式) - 在末行模式执行shell命令
输入:!命令
操作后,会切换至终端显示结果,按Enter后回到vim界面
gcc
- -I
指定头文件位置
gcc -I ./inc hello.c -o hello
- -c:
只做预处理、编译、汇编。得到二进制文件 - -g:
编译时添加调试语句,增加该参数后使用gdb调试 - Wall(Warning all):
显示所有警告信息 - D:
向程序中动态注册宏定义,用处:控制是否显示调试信息
静态库制作与使用
1.将.c文件生成.o文件
gcc -c add.c -o add.o
2.使用ar工具制作静态库
ar rcs libmymath.a add.o sub.o div1.o
3.编译静态库到可执行文件中
gcc test.c lib库名.a -o a.out
动态库的制作和使用
1.将.c文件生成.o文件(生成与位置无关的代码 -fPIC)
gcc -c add.c -o add.o -fPIC
2.使用gcc -shared 制作动态库
gcc -shared -o lib库名.so add.o sub.o div.o
3.编译可执行程序时,指定所使用的动态库(-l 指定库名(去掉lib和.so) -L 指定库的路径 -大写i 指定头文件路径)
gcc test.c -o a.out -lmymanth -L./lib -I./inc
4.运行可执行程序,运行./a.out出错!!!!
原因:
- 链接器:工作于链接阶段,工作时需要-l -L(制作库时已配置)
- 动态链接器:工作与程序运行阶段,工作时需要提供动态库所在目录位置。
解决动态连接问题:
【1】通过环境变量改变:expor LD_LIBRARY_PATH=动态库路径(临时生效,终端重启环境变量失效)
【2】 配置文件:
写入终端配置文件-> .bashrc
1)vi ~/.bashrc
2)写入expor LD_LIBRARY_PATH=动态库路径(建议使用绝对路径)
3). .bashrc或者source .bashrc或者重启终端,运行该文件使修改生效
4)./a.out运行成功
【3】将库文件拷贝到/lib下
【4】缓存文件法:
1)sudo vi /etc/ld.so.conf
2)写入动态库的绝对路径 保存
3)sudo ldconfig -v 使配置文件生效
4)./a.out 执行成功,可以通过ldd a.out 看库的路径
gdb调试
基础指令:
-g:使用该参数编译可执行文件,得到调试表
gdb a.out进行调试
list: list 1 列出源码。根据源码指定 行号设置断点。
b: b 20 在20行位置设置断点。
run/r: 运行程序
n/next: 下一条指令(会越过函数)
s/step: 下一条指令(会进入函数)
p/print:p i 查看变量的值。
continue:继续执行断点后续指令。
finish:结束当前函数调用。
until:执行完循环
quit:退出gdb当前调试。
其他指令:
run:使用run查找段错误出现位置。
set args: 设置main函数命令行参数 (在 start、run 之前)
run 字串1 字串2 ...: 设置main函数命令行参数
info b: 查看断点信息表
b 20 if i = 5: 设置条件断点。
ptype:查看变量类型。
bt(backtrace):列出当前程序正存活着的栈帧。
f(frame): 根据栈帧编号,切换栈帧。
display:设置跟踪变量
undisplay:取消设置跟踪变量。 使用跟踪变量的编号。
makefile
命名:makefile/Makefile
ALL: 指定makefile的终极目标
- 1个规则:
目标:依赖条件
(一个tab缩进)命令
hello:hello.c
gcc hello.c -o hello
目标的时间必须晚于以来条件的时间,否则会运行命令更新
依赖条件如果不存在,找寻新的规则来产生以来条件
- 2个函数:
src = $(wildcard ./*.c)
:匹配当前目录下所得的.c文件。将文件名组成列表,赋值给srcobj = $(patsubst %.c, %.o, $(src))
:将参数3中,包含参数1的部分,替换为参数2。将文件名组成列表,赋值给obj。
clean:(没有依赖)
-rm -rf $(obj) a.out "-"作用是,删除不存在文件时,不报错,顺序执行结束 - 3个自动变量:
$@:在规则的命令中,表示规则中的目标。
$^:在规则的命令中,表示所有依赖条件。
$<:在规则的命令中,表示第一个依赖条件。如果将该变量用在模式规则中,它可以将依赖条件列表中的依赖依次取出,套用模式规则。
模式规则:
使用自动变量可以进行匹配,将多个相似的步骤合并
add.o:add.c
gcc -c add.c -o add.o
sub.o:sub.c
gcc -c sub.c -o sub.o
div1.o:div1.c
gcc -c div1.c -o div1.o
#使用模式规则简化上面代码,两个%是当前一个匹配到对应值后面的必须与前面的值一样与*有区别
%.o:%.c
gcc -c $< -o $@
静态模式规则:
这里制定了模式规则给obj列表里的值用
$(obj):%.o:%.c
gcc -c $< -o $@
伪目标:
防止文件夹里有名为clean或者ALL的文件导致执行make命令无法正常运行
.PHONY:clean ALL
参数:
-n:模拟执行make、make clean
-f:指定文件执行make命令
系统编程
open、close函数
open函数:
int open(char *pathname, int flags) #include <unistd.h>
参数:
pathname: 欲打开的文件路径名
flags:文件打开方式: #include <fcntl.h>
O_RDONLY|O_WRONLY|O_RDWR O_CREAT|O_APPEND|O_TRUNC|O_EXCL|O_NONBLOCK ....
返回值:
成功: 打开文件所得到对应的 文件描述符(整数)
失败: -1, 设置errno
int open(char *pathname, int flags, mode_t mode) 123 775
参数:
pathname: 欲打开的文件路径名
flags:文件打开方式: O_RDONLY|O_WRONLY|O_RDWR O_CREAT|O_APPEND|O_TRUNC|O_EXCL|O_NONBLOCK ....
mode: 参数3使用的前提, 参2指定了 O_CREAT。 取值8进制数,用来描述文件的 访问权限。 rwx 0664
创建文件最终权限 = mode & ~umask
返回值:
成功: 打开文件所得到对应的 文件描述符(整数)
失败: -1, 设置errno
close函数:
int close(int fd);
错误处理函数:与 errno 相关。
printf(“xxx error: %d\n”, errno);
char *strerror(int errnum);
printf(“xxx error: %s\n”, strerror(errno));
void perror(const char *s);
perror(“open error”);
read和write实现cp
read函数:
ssize_t read(int fd, void *buf, size_t count);
参数:
fd:文件描述符
buf:存数据的缓冲区
count:缓冲区大小
返回值:
0:读到文件末尾。
成功; > 0 读到的字节数。
失败: -1, 设置 errno
-1: 并且 errno = EAGIN 或 EWOULDBLOCK, 说明不是read失败,而是read在以非阻塞方式读一个设备文件(网络文件),并且文件无数据。
write函数:
ssize_t write(int fd, const void *buf, size_t count);
参数:
fd:文件描述符
buf:待写出数据的缓冲区
count:数据大小
返回值:
成功; 写入的字节数。
失败: -1, 设置 errno