2017_10_21:
1. shell :unix系统
bash(伯恩为了linux系统重写的shell的缩写): linux系统
shell命令:
终端中敲入可以运行的正确命令。
shell命令解释器。
对应的命令-》对应的操作。
2. linux快捷键:
1>.history :我所用过的命令
结合ctrl+p(从下往上),结合ctrl+n(从上往下);
2>.光标移动
ctrl+b:向前移动
ctrl+f:向后移动
ctrl+a:移动到行首
ctrl+e:移动到行尾
ctrl+u: 删除光标前面的字符
ctrl+d: 删除光标后面的字符
3.linux系统目录结构:
没有盘符结构,是一种树结构。
1>.根目录 ;
2>./bin : binary 的缩写,这个目录存放着经常使用的命令:cp,mv,date等。
因为配置了环境变量,敲入命令,命令解释器就会到这个目录下面来找。
3>./boot : 这里存放的是启动linux时使用的一些核心文件,包括一些连接文件和镜像文件;
4>./dev : dev是device 的缩写,该目录下存放的是linux的外部设备,
在linux中访问设备的方式和访问文件的方式是相同的。
5>./etc : 这个目录用来存放所有的系统管理所需要的配置文件和子目录
6>./home : 当前环境中有多少个普通用户,各是什么?显示各自的用户目录。
7>. /lib : 这个目录存放着系统最基本的动态链接共享库,起作用类似于
windows里的dll文件,几乎所有的应用程序都需要用到这些共享库。
8>. /media : linux系统会自动识别一些设备,例如U盘,光驱等 ,当识别后,
linux会把自动识别的设备挂载到这个目录下。
9>. /mnt : 系统提供该目录是为了让用户临时挂载别的文件系统的,
我们可以把光驱挂载在/mnt/上,然后进入该目录就可以查看
光驱里的内容了。
10>. /opt : 这是给主机额外安装软件所存放的目录,比如你安装一个
oracle数据库 时就可以放到这个目录下,默认是空的。
11>. /proc : 这个目录是一个虚拟的目录,它是系统内存的映射,我们可以
直接访问这个目录来获取系统信息,这个目录的内容不是在硬盘
上而是在内存里,我们也可以直接修改里面的某些文件。
12>. /root : 该目录为系统管理员,也称为超级权限者的用户主目录。
13>. /sbin : s就是super user 的意思,这里存放的是系统管理员使用
的系统管理程序。
14>. /usr : 这是一个非常重要的目录,用户的很多应用程序和文件都
放在这个目录下,类似于windows下的program files目录。
4.用户目录:
1>. 绝对路径 : 从根目录开始写 :/home/itcast/aa
2>. 相对路径 :
. -> 当前目录简写
.. -> 当前的上一级目录简写
cd - :在邻近的两个目录中切换
cd ~ :跳到当前的用户目录。
3>. itcast@ubuntu:$
itcast:当前 登录用户
@:at 在
ubuntu:主机名
$: 普通用户
#: root用户
5. 文件和目录操作:
1>. 查看我的资产(目录);
2>. 查看文件内容:
cat:查看几十行以内的文件内容;
more:回车一行的看,空格翻页看。不能往前翻页。
退出按Q键或ctrl +c。
less:回车一行的看,空格翻页操作,ctrl+p一行一行
往前翻,ctrl+b往前翻页。(简单了解,不经常用)
head:默认显示文件 前十行
自定义 :head -5 [文件名],查看文件前5行。
tail:默认显示文件 后十行
6.创建软链接,相当于创建了一个快捷方式。
例如: ln -s hello.c hello.soft
此处要注意创建链接的对象要使用绝对路径,这样
之后随便移动软链接的位置,都可以用。
7.创建硬链接,相当于一份备份。
注意,原理上并没有发生拷贝,因为硬链接并不占据磁盘空间。
*linux文件系统的存储单元是块。
原理自己去查,inode结点保存文件信息。
8.文件或目录属性:
1>.wc 获取一个文本文件的信息。
2>.od 查看二进制文件。
3>.du -h 显示当前目录下所有文件的大小。
4>.df -h 显示当前磁盘情况。
5>.which ls 显示/bin/ls
对应的命令所在的路径。
对內建命令,如cd无法查看。
8.
查看当前登录用户:whoami
修改文件权限:
1.文字设定法:chmod [who] [+|-|=] [mode]
who:
文件所有者 :u
文件所属组 :g
其他人 : od
+:添加权限
-:减少权限
=:覆盖原来的权限
mode:
r:读
w:写
x:执行
2.数字设定法:
chmod 777 laowang
9.改变所属用户,改变所在组:
1.chown yinghuoai laowang 改变文件老王的所属用户为yinghuoai
2.chown yinghuoai:yinghuoai laowang “:”前面是所属用户,后面为所在组,都为yinghuoai
3.chgrp yinghuoai laowang 改变所在组:
前提:都得加sudo。
为什么要这样:chmod 777 太暴力了!!!
目录 必须有执行权限,这样我们才可以进去!!!
10.查找文件:
1.按文件名查找:
find ~/ -name filename
2.按文件大小查找:
find ~/ -size -10M -size +10k
3.按文件类型查找:
find ~/ -type f
查找普通文件
find ~/ -type p
查找管道文件
11.文件的检索:
1.查找文件里的字符串:
grep
12.U盘的挂载:
插上U盘,自动挂载到/media目录;
先卸载,sudo umount /media/ubuntu/ESD-ISO 卸载什么 ,参数是一个
然后挂载到/mnt 目录:
但是首先得得知设备的名字:
sudo fdisk -l
然后挂载:sudo mount /dev/sdb4 /mnt 把什么挂载到哪里,两个参数
所有怎么拿出去呢,cp 就行了
注意,不能在/mnt卸载,需要跳到其他目录再卸载。
其实也可以挂载到其他目录下,但是挂载的过程会覆盖 原有de
内容,所以最好是一个空目录。
13.压缩包管理:
gzip:--.gz格式压缩包
bzip2:--.bz2格式压缩包
1.tar:
参数:
c--创建--压缩;
x--释放--解压缩;
v--显示提示信息--压缩解压缩--可以省略
f--指定压缩文件的名字
z--使用gzip的方式压缩文件--.gz
j--使用bizp2的方式压缩文件--.bz2
压缩:
tar zcvf 生成的压缩包的名字(xxx.tar.gz) 要压缩的文件或目录
tar jcvf 生成的压缩包的名字(xxx.tar.bz2) 要压缩的文件或目录
把什么东西压缩成什么东西,需要两个参数
解压缩:
tar zxvf 要解压的文件(默认解压到当前文件)
还可以解压到指定目录:
tar jxvf 要解压的文件名 -C 解压到的目录
把什么东西解压到什么位置,两个参数,默认解压到当前文件夹 。
2.rar--必须手动安装该软件:
参数:
压缩: a
解压缩: x
压缩:
rar a 生成的压缩文件的名字(temp) 压缩的文件或目录
解压缩:
rar x 压缩文件名 解压缩目录
tty1-tty6:文字终端
tty7:桌面终端。
14.进程操作:
ps:
ps a
打印当前所有用户的信息
ps au
更加丰富化的信息
ps aux
查看没有终端的进程信息(会显示大量内容)
此时,可以使用管道进行重定向 ,其实就是过滤信息的作用。
指令1 | 指令2
指令1的输出作为指令2的输入,最终的处理结果才会显示
在屏幕上。
例如:ps aux | grep bash
就是ps aux 中的结果中 有bash 的信息
终端的作用,有无的影响。带终端,是为了和用户进行
交互的。没有,也就是不需要与用户交互。
每一个进程对应一个bash。
kill:
kill -l
显示kill 参数可选项,查看所有的信号
选择第9号杀死进程
kill -SIGKILL 进程的PID
15.环境变量:
env:打印当前进程下的所有环境变量
环境变量格式:key value值:
key = value1:value2:value3
如PATH=/usr/bin
top:
相当于linux下的任务管理器,但是只能看。
ctrl+c--关闭。
16.ping
linux: ifconfig 查看mac地址和ip地址。
ping ip地址 -c 4
链接4次就停下。
windows:ipconfig
如何得知域名对应的IP地址?
用nslookup :
nslookup www.baidu.com
17.ubuntu 下的用户管理:
添加用户:
1.sudo adduser + 用户名
addusr 是个脚本,所以比较简单
但是当用户名有大写字母的时候,就不能用adduser了。
2.useradd
useradd 是个命令,较为复杂
sudo useradd -s /bin/bash -g Robin -d /home/Robin -m Robin
用到的shell 用到的组
3.修改root用户的密码:
sudo passwd (root)
root 可有可无
4.deluser
sudo deluser 用户名
5.userdel
18.ftp服务器的搭建: --vsftpd
作用:单一,负责文件的上传和下载。
1.服务器端:
1.修改配置文件--如何修改配置文件
cd /etc
ls -l vsftpd.conf
sudo gedit vsftpd.conf
修改vsftpd.conf文件内容,
取消相关注释,并且使能相关设定。
2.重启服务--什么命令能够重启服务
sudo service vsftpd restart
2.客户端:
1.实名用户登录
ftp+IP(server)
输入用户名(server)
输入密码
文件的上传和下载 ,都是在客户端上输命令。,不允许操作目录,
如果想操作目录,只能压缩打包。
上传: put filename
上传的文件可以是登录之前,客户端的pwd
注意,上传的时候,两边的两个目录要搞清楚。
下载:
get filename
文件的下载。
2.匿名用户登录,用到的时候最多。
ftp+serverIP
用户名:anonymous
密码:直接回车。
创建了一个myftp 文件夹,我建在了用户目录下。
还需要修改 /etc/vsftpd.conf
指明这个文件夹为匿名用户ftp服务文件夹。
3.lftp客户端访问ftp服务器,相当于一个小工具
软件安装:sudo apt-get install lftp
然后就可以用了
lftp ip地址
输入“login”
put 上传文件
mput 上传多个文件
get 下载文件
mget 下载多个文件
mirror 下载整个目录及其子目录
mirror -R 上传整个目录及其子目录
19.nfs服务器的搭建:
作用:net file system 网络文件系统,它允许
网络中的计算机之间通过tcp/ip网络共享资源 。
1.安装软件:
sudo apt-get install nfs-kernel-server
2.创建一个欲共享出去的目录:
如: /home/xxx/xxx
3.打开配置文件:
sudo vi /etc/exports
4.写入共享目录的绝对路径,及对应权限
如:/home/ubuntu/ubuntu
、、、、、、、、、、、、、、、、
1.服务器端:
1.创建共享目录
mkdir dir
2.修改配置文件
/etc/exports
3.重启服务
sudo service nfs-kernel-server restart
2.客户端:
1.挂载服务器共享目录
sudo mount serverIP:sharedir /mnt
20.ssh服务器:
什么时候用?
其实我最经常用到的是用树莓派的时候。
无论何时何地,可以远程地对服务器进行操作。
sudo apt-get install spenssh-server
运用:
ssh [email protected]
ssh 用户名@ip地址
输入 yes.
退出:logout
scp命令:
super copy
可以在不同的主机间进行拷贝。
scp -r 目标文件名@目标主机IP地址:/目标文件的绝对路径 /保存到本机的绝对(相对)路径
拷贝目录需要加参数-r
linux 下切换7个终端:ctrl+alt +F1~F7,各个终端之间是互不影响的。
21.man和echo
man man
echo "hello linux"
查看当前的环境变量
env | grep PATH
echo $PATH
PATH:key-value 值,使用$就可以从变量中取值。
22.vi和vim
vim是vi发展过来的一款 文本编辑器。
三种工作模式:
1.命令模式:
打开文件之后,默认进入
2.编辑模式:
需要一些命令,切换到这种模式。
3.末行模式:
光标的移动:
H:向前 J:向下 K:向上 L:向后
0:光标移动到行首
$:光标移动到行尾
gg: 把光标移动到当前文本文件的开始位置。
G:把光标移动到当前文本的末尾位置。
500G:光标移动到第500行。
x:删除光标后面的一个字符
X:删除光标前面的一个字符
u:撤回 ,undo
dw:删除光标当前的字符串,一个单词。
d0:删除光标之前的内容
D:删除光标之后的所有内容
dd:删除光标所在的行。
4dd:删除4行。
vim中“删除”并不是真正的删除,而是剪切。
p:粘贴到光标所在行下面
P:粘贴到光标所在行
yy:复制
v:切换到可视模式
对于选中的内容
y:复制
d:删除
/stdio.h:
查找“stdio.h”
从光标开始向下查找,并返回头部。
?stdio.h:
查找“stdio
从光标开始向上查找,顶部之后,返回到尾部。
遍历时候的快捷键:
N/n
切换到文本模式的操作:
a-- 在光标所在位置的后边插入
A-- 在当前行的尾部插入
i-- 在光标所在位置的前边插入
I-- 在光标所在行的行首插入
o-- 在光标所在行的下边开辟一个新的行
O-- 。。。。。。。。。上。。。。。
s-- 删除光标后边的字符
末行模式:
输入
:300
跳转到300行。
进行字符串的替换 : 替换光标所在行的第一个tom,
:s/tom/jack
替换当前行的所有内容
:s/tom/jack/g
替换当前文件中的所有tom
:%s/tom/jack/g
替换其中某几行的tom
:27,30s/tom/jack/g
执行其他命令:
:!ls
水平分屏:
:sp
两个屏之间切换:
ctrl+w+w
保存所有的分屏:
:xall
垂直分屏:
:vsp
两个屏之间切换:
ctrl+w+w
!!可以用vim打造IDE
23.gcc 编译器:
gcc hello.c -I ./inclue -o hello
自定义的头文件存放的绝对路径。
-I ./include
在gcc编译的时候添加include 路径。
-D DEBUG
在gcc 编译的时候添加宏DEBUG ;
-O(0/1/2/3)
在gcc编译的时候优化等级,0不优化,3最高等级优化。
-Wall
在gcc编译的时候输出警告信息。
-g
在gcc编译的时候,添加调试信息,用于gdb调试。
24.静态库
1.命名规则:
1.lib+库的名字+.a
2.libmytest.a
2.制作步骤:
1.生成对应的.o文件
-c
2.将生成的.o文件打包
ar rcs + 静态库的名字(libmytest.a) + 生成的所有.o文件
3.发布和使用静态库:
1>.发布静态库
2>.头文件
也就是给用户发送
include目录和lib目录的文件
4.优缺点:
总结,最后怎么用呢?
一个总文件夹 all;
它包括3个文件夹,1个文件
3个文件夹分别是Lib文件夹,src文件夹,include文件夹
1个文件是main.c文件
lib文件夹存放 libmytest.a 之类的lib库文件 ,
这些库文件由src文件夹中对应的源文件编译生成
的*.o文件打包生成
src文件夹存放 add.c sub.c mul.c div.c 之类的子函数源程序
include文件夹存放 “head.h”之类的头文件。
最终使用:
举例:
假设我们所处的目录就是all文件夹目录:
gcc main.c lib/libmycalc.a -o sum -I ./include/
或者
gcc main.c -I include -L lib -l mycalc -o sum
其中-L:指定所有库的路径
-l:指定具体用到的库的名字。
最终执行:
./sum
nm libmycalc.a:
查看静态库中的内容
nm sum:
查看可执行文件的内容。
T--在代码区
注意,使用静态库的时候,打包的最小单位其实是*.o文件
我们要知道,*.a文件里有多个*.o文件,*.o文件里有多个
函数,我们在主程序中用到了哪些函数,也就是编译生成的
执行程序就把相应函数所在的*.o文件打包进去,也就是并不是一股脑
将*.a文件打包进去,切记。
如何验证呢?
用nm 命令。
静态库的优点:
1.发布程序的时候,不需要提供对应的库;
2.加载库的时候速度很快;
静态库的缺点:
1.库被打包到应用程序中,导致应用程序的体积很大。
2.如果库发生了改变 ,需要重新编译程序。
25.动态库,共享库
1.命名规则:
lib+名字+.so
2.制作步骤:
1.生成与位置无关的代码,(生成与位置无关的*.o文件)
gcc -fPIC -c *.o -I ../include
每一个应用程序执行起来时候,都会对应地分配一个虚拟
地址空间,虚拟地址空间在虚拟内存中,虚拟内存占用
硬盘的空间。针对32位操作系统,每个程序运行起来都会
分配一个0~4G的虚拟地址空间。
大致分:受保护区,代码段,已初始化全局变量区,
未初始化全局变量区,堆空间,共享库,栈空间,环境变量
,linux kernel (高地址1G)
*.o文件在打包生成的时候如果附加了绝对地址信息,也就是
如果调用到对应的*.o文件的时候,都会把它的程序放在
一个固定的位置。这是静态库。这就叫与代码有关。
而动态库在打包的时候,*.o不会被打包到可执行程序中
,只是做了符号的记录。
当程序执行之后,才开始加载动态库。
也就是把对应的*.o文件加载到虚拟地址的
共享库区域 。
然后怎么查找呢?采用相对地址的形式,就是偏移地址。
相对谁偏移呢?
就是相对程序加载到共享库区域的地址,加上语句在程序
中的偏移。
另外的话,共享库区域,还包括c标准库和
linux 直接IO函数。
2.将*.o文件打包生成*.so 文件。
gcc -shared -o libmycalc.so -I ../include
mv libmycalc.so ../lib
使用动态库:
1.gcc main.c lib/libmycalc.so -o sum -I include
或者
2.gcc main.c -I include -L ./lib -l mycalc -o sum
注意,用-l的时候要把lib库的名字掐头去尾。
ldd
例如: ldd sum
命令查看,
执行程序过程中所有依赖的动态库。
如果不能动态链接,后面会显示not found
注意,其中动态链接器程序帮助我们把对应的动态库
加载到应用程序中的。
动态链接器 ld-linux-x86-64.so.2
根据一个规则进行查找
什么规则呢?
就是环境变量。
哪个环境变量呢 ?
echo $PATH
查看。
动态库的环境变量又与此不同。
是另外的环境变量。
最终执行程序的时候出现错误,显示动态加载共享库失败。
怎么办呢?
解决方法:
改变LD_LIBRARY_PATH 环境变量的值。
export LD_LIBRARY_PATH=./lib
这样就解决了。
但是,这种方法只是临时性的。
所以,仅适用于开发过程中,临时导入作用。
那么怎么实现库的导入的永久设置呢?
写入当前用户的bash文件。
虚拟终端每次重新打开的时候,都会重新
读取一下.bashrc文件中的配置。也就是会更新
一下。
第4中方案,比较重要,也比较复杂:
1.需要找到动态连接器的配置文件;
2.冬天库的路径写到配置文件中;
3.更新--sudo ldconfig -v
-v:显示信息的输出。
举例:
cd /etc
ls -l ld.so.conf
vim ld.so.conf
添加
对应的动态库目录
/home/ubuntu/aa/xin/lib
总结一下,4种方法:
1.放到系统的根目录中,---不允许使用
2.临时测试
环境变量:LD_LIBRARY_PATH=将动态库的路径设置
将设置的值导入 系统环境变量。
当终端关闭,设置会失败。
3.不常用方法(永久设置)
在家目录的.bashrc文件中 添加一句话:
export LD_LIBRARY_PATH=动态库目录绝对路径
需要之后重启终端。
4.
1.需要找到动态链接器的配置文件
/etc/ld.so.donf
2.动态库的路径写到配置文件中--绝对路径
3.更新--sudo ldconfig -v
动态库的优点:
1.执行程序体积小
2.动态库更新了,不需要重新编译程序
前提是函数的接口没有发生变化。
动态库的缺点:
1.发布程序的时候,需要将动态库提供给用户
2.动态库没有被打包到应用程序中,加载速度
相对较慢。
26.gdb调试:
一个程序工程是包含多个程序文件的。
l 命令。
只会列出包含main函数的文件内容
如果我们想看其他文件的内容呢?或者调试其他文件呢?
比如说,想看sort.c文件 。
l sort.c:20
这样就会把sort.c文件中20行上下5行的内容列出来。
还有其他用法:
l sort.c:selection
这样就会把sort.c文件中selection函数周围10行的程序内容列出来。
比如一个for中。
i从0开始,到100
我们想在i=50的时候,让程序停下,
这个叫条件断点。
b 15 if i==15
其中15是程序中for语句内部的第一句所在的行号,
不然是不会挺的。注意!!!
b 行号
b 函数名:行号
以上几种设置断点的方法。
i b
查看断点信息
start
程序开始执行,且只执行一步
n
单步执行
c
继续执行直到断点。
s
进入到函数内部。
p(print) 变量名
查看对应的变量的值
ptype 变量名
查看对应的变量的类型。
比如一个for循环中i,j都在改变
我们每次单步运行的时候想要自动显示出i,j的变化情况,也就是追踪变量值。
可以在这之前
display i
dispaly j
之后再 n的时候,就会自动打印了。
取消追踪用:
undisplay 编号
编号如何获取呢?
info dispaly
查看获得。
u
跳出单次循环
finish
跳出所在函数。
d(delete) 编号
删除断点,通过相应的编号
怎么获取断点编号呢?
同样的,
i b
for循环中i通常是个累加量
如何能够自己在gdb中直接设置
i=10呢?
set val i=10
r(run)
另一种运行程序的方法
所以,注意,使用gdb其他功能之前,先把断点打上。
27.makefile
1.makefile的命名:
makefile 或者Makefile
2.编写makefile
vim makefile
规则:
3要素:目标、依赖条件、命令。
目标:依赖条件
命令
如果不存在就向下查找。
3.变量:
obj=main.o add.o sub.o mul.o
target=sum
$(target):$(obj)
gcc $(obj) -o $(target)
之后还有一句比较特殊的:
涉及到模式匹配。 也就是 之前的 main.o add.o sub.o mul.o--
中的.o前面的字符都会自动匹配。下面的语句。
%.o:%.c
gcc -c $< -o $@
什么是$< ?什么是$@呢?
makefile 中的自动变量。
$<:规则中的第一个依赖。
$@:规则中的目标。
$^:规则中的所有依赖,即变量obj。
要求:
自动变量只能在规则的命令中使用 。
makefile中提供的函数,所有的函数都是有返回值的。
而返回值的获取也是需要$符号。
makefile中函数的使用:
比如:
src=$(wildcard ./*.c )
obj=$(patsubst ./%.o, ./%.c, $(src)) 匹配替换函数,用的是模式匹配,不是*
如果加一个额外语句:
clean:
rm $(obj) $(target) -f
这条命令没有依赖,
当我们在外面
make clean 时,就只执行这条语句,只生成clean
,其他的语句都没有执行,也就是最终的目标sum
也没有生成。
-f
强制执行。
在命令之前加“-”,就是如果这条命令执行失败了
,就忽略掉这条命令,继续向下执行
如:
-mkdir aa
28.c库函数
c库函数提供了一个io缓冲区。为什么呢?
因为我们读的文件是磁盘文件,
磁盘都是机械硬盘,读取速度是ms级别
内存读取速度是ns级别
两者相差一百万倍。
FILE* fp;
fp指向了一个结构体
结构体里面有 文件描述符 -》索引到对应的磁盘文件,比如hello.txt
文件读写指针位置 -》 读写过程中指针的实际位置,比如hello.txt 中第10行
当前文件指针位置,通过fseek()函数操作。
I/O缓冲区(内存地址) -》 通过寻址找到对应的内存块。
数据从内存缓存中的数据刷新到磁盘上:
1.刷新缓冲区:fflush
强制性地把缓存中的数据刷到硬盘上
2.当缓冲区满了,自动就会刷到硬盘上
3.正常关闭文件:
1>.fclose
2>.return(main函数)
3>.exit(main函数)
注意,linux系统函数,是没有提供I/O缓冲区的。
这是与c库函数的不同点之一。
29.虚拟地址空间
32位系统和64位系统
为每一个进程分配0~2^32 和0~2^64
的虚拟地址空间
也就是4G和
4G中0~3G是用户空间,后面1G是linux kernel
linux kernel 内核区 部分还有PCB进程控制块
指向文件描述符表,其实是一个数组0~1023
整形数组,宏定义。
最前面,0 标准输入
1 标准输出
2 标准错误
默认是打开状态。
后面的序号,每打开一个新文件,
则占用一个文件描述符,而且使用的
是空闲的最小的一个文件描述符。
内核区可以做什么呢?
可以做 内存管理,
进程管理(PCB就属于这一部分),
设备驱动管理,
VFS虚拟文件系统。
可执行文件是elf格式。
命令: file sum
#define NULL (void*)0
这条语句指向哪呢,就是从0开始的0~4k
地址,受保护的地址。
ELF:
.bss(未初始化全局变量)
.data(已初始化全局变量)
text(代码段,二进制机器指令)
栈空间(小):分配地址,高地址-》低地址
堆空间(大):分配地址,低地址-》高地址
那么说回来,我们为什么要用什么鬼
虚拟空间
cpu为什么要使用虚拟地址空间与物理地址空间映射,
解决了什么问题?
1.方便编译器和操作系统安排程序的地址分布。
程序可以使用一系列相邻的虚拟地址来
访问物理内存中不相邻的大内存缓冲区。
2.方便进程之间隔离
不同进程使用的虚拟地址彼此隔离,
一个进程中的代码无法更改正在由
另一进程使用的物理内存。
3.方便OS使用你那可怜的内存
程序可以使用一系列的虚拟地址来访问大于
可用物理内存的内存缓冲区。
当物理内存供应量变小时,
内存管理器会将物理内存页(通常大小为4KB)
保存到磁盘文件。
数据或代码页会根据需要在物理内存与磁盘之间移动。
30.C库函数和系统函数的关系:
c标准函数
printf函数->标准输出stdout:FILE*
调用write函数将文件描述符传送
到linux系统API
应用层: write(fd,"helo",5)
操作0~3G
通过用户空间->内核空间 的转换
系统调用:
sys_write()
操作3G~4G
调用设备驱动
内核层设备驱动函数:
通过设备驱动操作硬件
硬件层:
将hello输出到显示器。
31.linux 系统常用I/O函数:
1.open()函数
光标移动到对应的函数字母上
按下 alt+K
跳转到对应的函数帮助文档。
打开方式:
O_RDONLY
O_WRONLY
O_RDWR
可选项:
O_CREAT
文件权限:
本地有一个掩码
用 umask
可以查看。
掩码 可以修改。
也是用umask
如: umask 022
所以,文件实际的权限
给定的权限
本地掩码(取反)
按位与操作
得出实际的操作。
O_TRUNC
O_EXCL
O_APPEND
2.用open函数判断一个文件是否已经存在。
fd=open("myhello",O_RDWR | O_CREAT | O_EXCL,0777);
3.将文件截断为0:
fd=open("myhello",O_RDWR | O_TRUNC);
需要注意的地方就是:
对函数的返回值进行判断
,最后输出。
2.read()函数:
返回值:
1. -1 读文件失败
2. 0 文件读完了
3. >0 读取的字节数
3.write()函数:
返回值:
4.lseek()函数:
1.获取文件大小;
2.移动文件指针;
3.实现文件拓展。只能往后拓展,不能往前拓展。
50m拓展为100m。
int ret = lseek(fd,2000,SEEK_END);
向后拓展2000.必须在最后做一次写的操作。
不管写什么,随便写点东西。
write(fd,"a",1);
32.linux文件操作相关函数:
1.stat函数:
获取文件的属性信息。
使用举例:
stat english.txt
通过stat函数实现ls -l功能。
对参数的分类:传入参数,传出参数。对应于读参数,写参数。
stat函数,穿透(追踪)函数--软链接,比如vi
lstat函数,不穿透(不追踪)函数。比如一些命令ls -l。rm
2.access函数
用man 2 access 进行函数查询
3.strtol函数
4.chown函数
5.man 5 passwd 密码文件
6.truncate函数
7.link函数
创建一个硬链接。
8.symlink函数
创建一个软链接。
9.readlink函数
读一个软链接。
10.unlink函数
1.如果是符号链接,删除符号链接;
2.如果是硬链接,硬链接数减一,当减为0时,
释放数据块和inode;
3.如果文件硬链接数为0,但有进程已打开该文件,
并持有文件描述符,则等进程关闭该文件时,kernel材真正
去删除该文件。