目录

  • 知识点
  • 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

未知文件。

文件权限说明

linux 可编程 gpu linux平台编程_linux


目录项详细信息

文件权限 硬链接计数 所有者 所属组 大小 时间 文件名/文件夹名

权限具体展开

-rw-r—r—

1234567890

1代表文件类型

234代表所有者读写执行权限

567代表同组用户读写执行权限

890代表其他人读写执行权限

r(Read,读取):对文件而言,具有读取文件内容的权限;对目录来说,具有浏览目录的权限。
w(Write,写入):对文件而言,具有新增,修改,删除文件内容的权限;对目录来说,具有新建,删除,修改,移动目录内文件的权限。
x(eXecute,执行):对文件而言,具有执行文件的权限;对目录了来说该用户具有进入目录的权限。

gcc编译

gcc编译可执行程序4步骤:预处理、编译、汇编、链接

linux 可编程 gpu linux平台编程_命令模式_02


数据段合并

linux 可编程 gpu linux平台编程_linux_03

动态库和静态库理论对比

  • 静态库在文件中静态展开,所以有多少文件就展开多少次,非常吃内存100M展开100次,就是1G,但是这样的好处就是静态加载的速度快
  • 使用动态库会将动态库加载到内存,10个文件也只需要加载一次,然后这些文件用到库的时候临时去加载,速度慢一些,但是很省内存。

动态库和静态库各有优劣,根据实际情况合理选用即可。

linux 可编程 gpu linux平台编程_命令模式_04

系统调用和(库函数比较—预读入缓输出)

linux 可编程 gpu linux平台编程_命令模式_05

  • 系统函数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 安装包名
更换软件源:
系统设置->软件和更新->下载自…
换软件源过后要更新软件列表

软件包安装:

linux 可编程 gpu linux平台编程_数据_06

压缩、解压

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

三种工作模式

linux 可编程 gpu linux平台编程_linux_07


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文件。将文件名组成列表,赋值给src
    obj = $(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