发现typora也是markdown,正好传上来节省电脑内存
ch1
UNIX-MINIX-GNU-Linux kernel-GPL-POSIX
GNU:创造一套完全自由的操作系统
GPL:自由软件协议
POSIX:操作系统为应用程序提供的接口标准
发行版本:RedHat CentOS Debian Fedora Ubuntu
操作系统
1.管理计算机硬件资源
2.为程序运行提供环境
3.多任务运行与调度
4.文件存储管理
linux 操作系统特点
1.c语言编写–可移植性强
2.多用户同时访问–适合环境
3.通过shell与os互动
linux体系结构
linux内核:
1.os核心 启动时加载进入内存
2.直接与硬件交互
3.作用
1)管理内存 2)调度任务进程 3)执行系统调用
shell:
1)用户与os kernel的交互接口
2)用户指令的解释器
3)每个登录用户有一个shell为其工作
采用命令行解释方式与linux交互
种类:bash TCshell
参看命令信息办法:man 命令/info 命令名/命令名 --help
echo -e(转义字符)
uname:查看操作系统信息
who:查看登录用户信息
date:显示系统时间
ch2
linux:一切都是文件
Linux文件
1.普通文件:仅包含字符流的数据文件(eg:文本文件/二进制文件)
2.目录文件:文件夹和子目录信息(文件名/inode号)
3.设备文件:代表设备,完成对设备的读取/写入
系统目录
/根目录
/bin:unix常用命令
/sbin:管理员常用命令 eg:fdisk/mkfs
/etc:系统文件(passwd用户基本属性,shadow密码信息)
/dev:设备文件目录
/lib:库文件
/var:可变文件目录(eg:打印、邮件)
/tmp:临时文件目录
文件系统相关命令
ls
cd
mkdir
rmdir -p(删除空目录)
cp -b (备份)-i (问)-n(不覆盖)-R
mv -b -i -n
rm -f -i -R
tar -cvf(创建)/xvf(提取)
cat
gzip -d(解压)/-k(保留原文及)/-l/-r
用户管理相关命令
sudo
adduser
passwd -d/-l/-u
usermod
deluser
su -c
文件属性
文件类型:
文件类型属性 文件权限属性 文件所有权 文件大小 文件最后修改时间
-/d/l rwxrwxrwx(所有者/用户组/其他用户)
文件权限:
类别 | 操作 | 权限 |
---|---|---|
u 用户 | + 增加权限 | r 读权限 |
g 用户组 | - 删除权限 | w 写权限 |
o 其他用户 | = 指定绝对权限 | x 执行权限 |
a 全部 |
2.八进制权限表示
umask 掩码
最终权限=默认权限码-权限掩码
chown/chgrp 名字 文件名
文件链接:
每个文件通过唯一inode号与一个inode表格连接 包含文件的属性
命令:ls -i
一个文件:多个文件名 称为多个链接 可以通过任意链接访问文件
ln创建硬链接(同一个inode号 不同文件名):1.防止意外删除 2.位置移动时也可以访问
ln -s 创建符号链接:创建一个拥有独立inode文件(指针文件)指向链接的文件(类似快捷方式)
改变文件类型
stat 文件属性 -f:文件系统属性
touch -a/-m/-c/-t
wc:行数 单词数 字符数 -l -w -c
find path –option expression
ch3
shell工作原理
用户登录时:启动shell进程,用户注销时终止
元字符–实际操作参数–指令传给内核
echo $SHELL查看类型
shell 命令元字符
通配符
通配符 | 匹配内容 |
---|---|
* | 任意数量的任意字符 |
? | 单个任意字符 |
[abc] | a, b, c中的任一个字符 |
[a-z] | ASCII码值在a与z中间的任一个字符 |
[!a-z] | 不在a-z范围内的任一个字符 |
!(fname) | 除fname之外的所有文件名 |
!(f1|f2) | 除f1和f2之外的所有文件名 |
转义符
1.在通配符之前加上\
2.单引号:通配符/变量名/命令
双引号:通配符
命令替换
``=命令结果
$(命令)
重定向
输入:键盘 (标准输入流)
输出:显示器(标准输出流/标准错误流)
三种标准输入输出源:终端/文件/管道
文件描述符 | 含义 |
---|---|
0 | 标准输入 |
1 | 标准输出 |
2 | 标准错误 |
3… | 其他文件 |
cat - (foo) 似乎是输入的内容打印到屏幕上
输出:echo content >/>> file
输入:wc<file
标准错误输出重定向:cat ()2> errorfile(出错就输入errorfile)
互相重定向:1>&2 2>&1(&2 &1相当于管道)
过滤器:同时使用输入输出重定向
组合命令:(){}组合起来,共享输入和输出源
管道:命令1|命令2
shell脚本
#!/bin/bash
shell程序变量
环境变量:
shell变量:全为字符串类型
设置:export变量名=变量值
引用:$变量名 查看:env
SHELL/HOME/PATH/PWD/UID/RANDOM
修改环境变量:1.shell中修改 仅在shell中生效
2.启动配置文件中修改 1)系统配置文件:/etc/profile 2)用户配置文件:~/.profile ~/.bashrc
设置路径变量:export PATH=“$PATH:newpath”
用户自定义变量引用和赋值:
变量引用 | 变量替换 |
---|---|
$变量名 | 变量值 |
${变量名} | 变量值 |
${#变量名} | 变量值长度 |
变量赋值 | 赋值语义 |
---|---|
y=${x-value} | 若x有值,则y=x,否则y=value |
y=${x=value} | 若x没有值,则y=x=value,否则y=x |
y=${x+value} | 若x有值,则y=value,否则不操作 |
y=${x?value} | 若x有值,则y=x,否则在标准错误输出value |
操作 | 返回值 | 示例:var=~/my/file.txt |
---|---|---|
${var#s} | 去掉从左边开始第一个匹配s的子串 | ${var#*/}=my/file.txt |
${var##s} | 去掉从左边开始最后一个匹配s的子串 | ${var##*/}=file.txt |
${var%s} | 去掉从右边开始第一个匹配s的子串 | ${var%/*}=~/my |
${var%%s} | 去掉从右边开始最后一个匹配s的子串 | ${var%%/*}=~ |
${var:m:n} | 提取从m位置开始往后的n个连续字符 | ${var:2:5}=my/fi |
操作 | 返回值 | 示例**😗* var**=~/my/file.txt** |
---|---|---|
${var/s/t} | 把第一个匹配s的串替换成t | ${var/t/e}=~/my/file.ext |
${var//s/t} | 把所有的匹配s的串都替换成t | ${var//t/e}=~/my/file.exe |
运算符:let命令(shell内部)数值运算
$(()) 也能运算
bc命令:支持浮点数/管道
echo“scale=n;ibase=k;obase=k;XXXX”|bc
数组:declare -a name
value=(0 1 2 3)
${array[i]}. a r r a y [ @ ] / {array[@]}/ array[@]/{array[*]} ${#array[@]}:数组元素个数
unset array/unset array[i]
shell程序语句
命令行位置参数:$0 $1
read变量表 -n-t-p-s
命令退出状态: 0/1 echo $?
shell控制结构语句:1)顺序;2)&&(前成功则后) ||(前失败则后)
条件测试命令:字符串比较/数字比较
字符串比较运算符 | 意义 |
---|---|
= | 等于 |
!= | 不等于 |
-n str | str不为空 |
-z str | str为空 |
str | str被赋值且不为空 |
文件特性检查:
命令 | 意义 |
---|---|
[ -e file ] | file存在 |
[ -f file ] | file存在并是一个常规文件 |
[ -d file ] | file存在并是一个目录 |
[ -L file ] | file存在并是一个符号链接 |
[ -rwx file ] | file存在且可读可写可执行 |
[ -s file ] | file存在且大小大于0 |
[ f1 –nt f2 ] | f1比f2更新 |
[ f1 –ot f2 ] | f1比f2更旧 |
[ f1 –ef f2 ] | f1被链接到f2 |
if语句:
if
then
else
fi
if
then
elif
then
else
fi
复合条件:结合&& || -a -o !
case:
case $var in
mode1)command1
command2
...
commandN
;;
mode2)command1
command2
...
commandN
;;
esac
for:
for i in $list
do
done
for i in {1..100}
for i in 1 2 3 4 5
while/until 相反
while/until expr
do
done
break/continue
function() {
statements
return value
}
shell输入输出流
ch4
简单过滤器
pr 改变文件打印格式
head/tail -n k 前k行/后k行
cut:垂直化分 -c (字符)-f (字段)-d (分隔符)eg:cut -c1-5 XXX
paste:垂直粘贴文件 -d分隔符 -s合并行
sort:
-t char 用char作为分隔符识别字段
-k m,n 对第m个字段开始到第n个字段结束进行排序
-k m.n 对第m个字段的第n个字符进行排序
-u 删除重复行
-n 数值排序
-r 反转顺序排序
-f 不区分大小写
-c 查看文件是否有序
-o file 将输出存入文件file中,可以和源文件同名
uniq:定位重复行/非重复行 -d/-u/-c
tr:将set1中的字符替换为set2 -d 删除 -s压缩连续字符
cmp:-b(第一个)/-l(所有)/-i num1 num2
comm -1(第一列独有的行) -2(第二列独有的行) -3(共有的行)隐藏
diff
正则表达式过滤器
grep命令查找文件中某一模式 —使用正则表达式
模式语句 | 匹配含义 |
---|---|
[pqr] | p,q,r中的单个字符 |
[a-z] | a到z之间的任意单个字符 |
. | 任意单个字符 |
a* | 0个或任意多个a字符 |
a{m,n} | a字符出现m到n次 |
[^pqr] | 不是p,q,r的单个字符 |
^exp | exp模式位于行首 |
exp$ | exp模式位于行尾 |
模式语句 | 匹配含义 |
---|---|
a+ | 1个或任意多个a字符 |
a? | 0个或1个a字符 |
exp1|exp2 | 匹配exp1或exp2 |
(a1|a2)a3 | 匹配a1a3或a2a3 |
grep -G基本-E拓展 -n行号 -c出现次数 -e只能输入连字符开头单个字符匹配 -x匹配整行 -i不分大小写 -v列出不匹配的行 -l只列出匹配模式的文件
sed流编辑器:对数据流进行定位操作 —通配符?
sed “” 文件名
匹配方式:1)k行 2)/pattern/
-e 多条指令
action | 功能 |
---|---|
i、a、c | 插入、追加和修改文本 |
d | 删除行 |
p | 在标准输出上打印结果 |
q | 读取到指定行后退出 |
r fname | 将文件fname的内容放在行后 |
w fname | 将指定行写入文件fname |
= | 打印指定行号 |
s/str1/str2/ | 用str2替换指定行中出现的第一个str1 |
s/str1/str2/g | 用str2替换所有的str1 |
标记正则表达式:
正则表达式 | 匹配含义 |
---|---|
& | 在目标模式中指代源模式 |
(pattern) | 标记源模式中的pattern,在目标模式中使用\k引用 |
(通配符、正则表达式都能使用)
awk编程
1.文字处理和报表制作工具
2.合并几个过滤器功能,独立实现程序设计
3.可识别、处理字段
4.可执行数值设计
5.接受类似拓展正则表达式结构
6.类似c的程序设计结构
7.可使用内置变量/函数
print/printf:-左对齐 \n换行符
管道、重定向 文件加双引号
awk -F: -f XXX.awk filename
引用shell脚本位置参数 加单引号
数组和变量规则相同 索引会根据一定规则自动变为字符串
内置数组:储存环境变量 ENVIRON数组 有HOME/PATH等
有内置变量:例如NR 以及内置函数
ch5
命令行参数
argc 储存个数 argv储存命令行参数
开发工具
编译器gcc
.c-(预处理).i-(编译).s-(汇编).o (链接)–可执行文件
文件类型 | 对应程序 | 文件类型 | 对应程序 |
---|---|---|---|
.c | C语言源程序 | .s | 汇编语言源程序 |
.i | 经过预处理的源程序 | .h | 预处理文件(头文件) |
.a | 编译后的库文件 | .o | 目标文件 |
选项 | 含义 | 选项 | 含义 |
---|---|---|---|
-o file | 将目标文件保存到file | -I dir | 在头文件搜索路径中加入dir |
-E | 只做预处理,生成经过预处理的.i文件 | -L dir | 在库文件搜索路径中加入dir |
-S | 只做预处理和编译阶段,生成汇编代码.s文件 | -l lib | 连接库文件lib |
-c | 不做连接步骤,生成.o目标文件 | -O[0-3] | 根据指定级别进行编译优化 |
c语言程序源文件:
1)头文件.h 系统函数声明/用户自定义函数声明 2)源文件.c 3)库文件 .a (静态).so(动态)-l引用 lib开头
保留.o 1)a ,b当依赖的文件a更新时 只需要重新编译a,直接链接b.o
2)合并一组.o 构成库
3)发现文件更新:比较 .c .o修改时间
编译更新make
makefile:target:dependency_list
(tab) command……
基名称相同:不需要command_list
可省略同名源文件.c
变量声明:var=value和使用:$(var)
预定义变量/自动变量
变量名称 | 含义 |
---|---|
CC | C编译器名称,默认为cc |
AS | 汇编器名称,默认为as |
RM | 文件删除命令名称,默认为rm –f |
AR | 库文件管理命令名称,默认为ar |
$* | 不包含扩展名的目标文件名称 |
$+ | 所有依赖文件,以空格分开,可能出现重复 |
$< | 第一个依赖文件名称 |
$? | 所有时间戳比target文件晚的依赖文件 |
$@ | 目标文件的完整名称 |
$^ | 所有不重复的依赖文件 |
生成库ar:生成静态库命令
将.o打包成一个静态库
类似于tar命令
libname.a
生成动态库:gcc -shared libname.so
使用:-l name -L dir
静态库 | 动态库 |
---|---|
.a | .so |
在链接时插入目标文件 | 在运行时调用 |
运行时不需要库文件 | 运行时需要指定库文件路径 |
可执行文件占用空间大 | 可执行文件占用空间小 |
-l命令优先选择动态库
调试工具gdb
命令 | 含义 |
---|---|
list | 显示10行源代码 |
list m,n | 显示m到n行源代码 |
run | 执行程序,直到下一个断点 |
cont | 继续执行 |
next | 执行下一条语句,函数体看成一条语句 |
step | 执行下一条语句,进入函数体 |
break n | 在第n行设置断点 |
break function | 在调用函数function的行设置断点 |
break n condition | condition为真时,在第n行设定一个断点 |
watch x | 设定对变量或表达式x的观察,在每次x值变化时暂停 |
whatis x | 显示变量或表达式x的类型 |
display/print x | 显示变量或表达式x的值 |
quit | 退出gdb调试环境 |
版本控制工具
c语言系统函数库
数学函数
rand()
srand(u int seed=time)
字符函数
eg:isalnum
系统时间函数
time(*t)
环境控制函数
char* getenv(const char *name)
int setenv(const char *name, const char *value, int overwrite)
内存分配函数
void *malloc(size_t size)
void *calloc(int num, size_t size)
void free(void *p)
操作:void *memset(void *buffer, int c, int count)
void *memcpy(void *dest, void *src, int count)
int memcmp(void *buf1, void *buf2, int count)
shell命令:int system(const char *string)
错误处理:void perror(const char *str)
open/close/write/read
ch6
linux中进程基本知识:
进程:执行中的任务实例
linux:多进程并发执行
一个程序 --产生(创建)多个进程
进程 --由内核调度
除第一个进程外 --都有父进程
shell进程 --父进程为init进程
ps:显示进程属性
-e/-A所有 -a用户进程 -ax系统进程 -f详细进程信息 -l显示进程状态 -u CPU和内存占用情况
进程状态:R/S/D/T/Z
虚拟地址空间:运行一个c程序时开辟一片虚拟地址空间供访问
命令行参数和环境变量:栈底部
stack栈:函数参数、局部变量、返回地址
动态共享库
堆heap:动态分配内存
数据:全局变量、静态变量
程序文本:要执行指令
init进程:在系统启动时存在 绝不会终止
是随后所有进程的祖先进程
守护进程:1)没有和终端相关联 2)不能读写终端 3)处于睡眠状态 4)接受输入信号时被唤醒 5)TTY中用?表示
进程控制:
任务控制:
1)command &
父进程不会等待子进程退出 shell显示pgid和pid
2)nohup command &
将标准输出和错误输出放入nohup.out
用户注销后后台程序仍然运行
作业控制命令 | 功能 |
---|---|
fg | 将任务移到前台运行 |
bg | 将任务移到后台运行 |
[Ctril+z] | 挂起当前的前台任务 |
jobs | 列出活动任务 |
kill | 杀死任务 |
%PGID %str(以str开头) %?str(包含str任务名)
c语言中实现进程属性控制:
int getpid()返回当前进程pid getppid()返回父进程pid
进程创建:
只能由另一个进程创建
创建机制:fork创建副本 exec覆盖 wait等待终止并记录退出状态
子进程会继承父进程:1)创建进程的用户uid和组gid 2)运行目录 3)父进程中打开的所有文件描述符 4)环境变量
用户定义的变量不会被继承
fork:在父进程中返回子进程pid 子进程中返回0
execl execv 给路径 1)给一个字符串列表 2)给一个字符串数组
execlp execvp 给出程序文件名 在PATH中去寻找
睡眠:
中止:
僵尸态:子进程结束,但父进程没有收到退出状态
危害:占用有限的进程号
进程退出:释放占有的资源 保留进程号/退出状态
父进程退出:init进程接管子进程 接收退出状态
wait:一直等待直到子进程结束,返回死亡进程pid
进程通信:
信号
键盘键入:c+z sigtstp挂起 c+c sigint终端中断 sigquit退出终端
硬件异常:算术异常sigfpe 内容违规sigsegv 非法指令sigill
c程序:生成信号的函数 eg:alarm sigalarm
其他:sigchild通知死亡 sigtin组织访问终端
信号编号 | 信号符号名称 | 功能 |
---|---|---|
2 | SIGINT | 中断当前终端,Ctrl+c |
3 | SIGQUIT | 退出当前终端,并生成一个核心文件, Ctrl+\ |
9 | SIGKILL | 杀死进程,不能被忽略或捕获 |
15 | SIGTERM | 终止进程,可能被忽略(kill命令默认参数) |
20 | SIGTSTP | 挂起当前前台进程,Ctrl+z |
17 | SIGCHLD | 内核通知父进程子进程终止 |
kill -s 信号 pid(sigterm默认)
信号相关的系统调用:1)sigaction 2)alarm 3)pause 4)kill
管道
无名管道调用:同源间进程通信
int pipe(int fd[2])
Read fd[0] write fd[1]
命名管道调用:FIFO
阻塞问题
消息队列
消息的链表:存放在kernel中,由消息队列标识符表示
一个进程向另一个进程发送数据块
消息类型:结构体 1)消息类型 2)text
系统调用:msgget创 名字+权限msgsnd发 标识符+指针+大小+是否为空 msgrcv收(消息类型 =0第一个可用信息 >0同类型 <0 类型小于其绝对值的消息) msgctl控 标识符+命令+指向权限的指针
共享内存
将同一段共享内存连接到自己的地址空间,所有进程都可以访问
未提供同步保护机制
shmget名字+大小+权限 shmat id+地址+0 shmdt地址 shmctl 同上
线程:
基本概念
进程内执行单元/可调度实体
线程创建和控制
共享:地址空间/文件系统资源/文件描述符、信号处理程序
用户进程:调度过程及算法完全由用户决定
内核进程:os管理
可实现一对一/一对多/多对一的关联
并发执行/自己的数据段、代码段/花费CPU资源较少
pthread_create:id,null,指向的函数代码,执行参数
pthread _exit 存储退出值 使自身线程退出
Pthread_join 等待线程结束接受退出值id +退出值
线程属性
属性名称 | 是 | 否 |
---|---|---|
绑定属性 | 一个用户级线程固定的分配给一个内核级线程 | 用户级线程与内核级线程的关系不是始终固定的,而是由系统来控制分配 |
分离属性 | 一个线程结束时会立即释放它所占用的资源 | 只有当pthread_join()函数返回时,该线程才释放自己占用的资源 |
堆栈地址/堆栈大小/优先级
线程同步与互斥
互斥:调度顺序不确定,对共享数据的修改也不确定 --确保只有一个线程访问共享资源
同步:多个线程在同步顺序上的协调
同步互斥机制:1)互斥锁
2)条件变量:与互斥锁一同使用 不满足条件则阻塞线程 释放互斥锁 改变变量时唤醒线程 再判断是否获得锁
3)信号量 P/V操作
对计数器信号量sem加减 p-1(<0阻塞) v+1(>0唤醒)
互斥:只设置一个信号量 同步设置多个来实现顺序执行
sem_init 1.指向信号量结构的指针 2.不为0进程间共享 0线程间共享 3.
ch7
TCP/IP网络架构
OSI TCP/IP模型
TCP:面向连接的协议 可靠性高 传输过程复杂 占用资源多
UDP:不面向连接的协议 可靠性差 传输效率高
socket概述
I/O 接口 “IP地址+端口号”
网络通信:通过socket标识
可作为文件描述符 传给Read/Write
主要为TCP/UDP
TCP通信流程:
server端—建立socket-》bind-〉listen-》accept-〉send recv-》close
client端—建立socket----------------〉connect()-》send/recv-〉close
UDP通信流程:都是 建立socket-》bind-〉recvfrom/sendto-》close
socket编程
主机序(4字节存储 大端序/小端序)–网络序(单字节传输):htons/htonl(对整型数字有效)
主机名和IP地址:
主机名:gethostname(名字+长度)
gethostbyname(名字)返回指向的指针
inet_ntoa(in_addr) 32 位–》A.B.C.D
Inet_addr (string)A.B.C.D->32位
UDP:
recvfrom 同recv 加上from端网络地址(struct sockaddr*)+长度sizeof
sendto 同send 加上to端网络地址+长度sizeof