一 Unix和Linux系统介绍
Unix / C
Unix 操作系统 开源
安全性高
熟练应用操作系统 Linux
Linux / C
C语言是基础
典型的Linux操作系统:
Ubuntu CentOS Redhat fedora UOS 麒麟操作系统
ctrl + alt + t ---> 打开终端
Linux 下一切皆文件
二 基本命令
clear 清屏 或者 按快捷键 ctrl + l
ls 显示当前目录下的文件和文件夹(目录)
ls -l l表示list 显示文件和文件夹的详细信息
ls -a 显示当前目录下的所有文件和文件夹(目录),
包括隐藏文件
ls -ltr 按照时间顺序显示所有的文件和目录
-rw-r--r--
0 110 100 100
0644
属主 属组 其他
pwd 显示当前所在的目录
vim 有三种模式:
默认进去视图模式
编辑模式 : a o ---》 即可编辑文件
命令模式 : shift + : ---> 即可进入命令模式
退出文件 : 在命令模式下,输入wq
cd 命令
cd
cd ~ 进入的是用户工作的家目录
cd - 撤销上一步的cd 操作
cd / ----> 绝对路径 cd /bin
cd /home/liuang
cd ../../liuyang ----> 相对路径切换
/ 指的是根目录
.. 指的是上级目录
. 代表当前目录
创建文件夹:
mkdir xxx
创建文件:
以下两个命令
touch xxx.c xxxx.h xxxx.txt
vim/vi xxx.c xxxx.h xxxx.txt
查看文件的内容:
cat xxx.c
练习:1.在/home/liuyang 目录下创建一个文件夹iot,
在iot文件夹下,创建1.txt 和 test.c 文件。
2. 在1.txt文件中写一句话,
在test.c 中写hello world程序
编译代码:
gcc test.c
gcc test.c -o xxx 这里面xxx就是生成的可执行文件
gcc -v 查看编译器的版本信息
file test.c file 查看文件的类型
file a.out
./a.out 执行可执行程序
cp 命令:
拷贝文件或者目录
cp xxx.c yyy.c
cp iot chenwenhong -R/-r
注意:拷贝目录时,需要加-r选项
rm 命令:
删除文件或者文件夹
注意:删除目录时,需要加-r选项
注意注意: 千万不要删除"/" 目录下的系统文件
tar 命令:
压缩和解压的命令:
压缩: tar -zcf xxxx.tar.gz xxxx
解压: tar -xf/-xvf xxxx.tar.gz
.tar.gz 是Linux中最常用的一个压缩类型
xxxx.zip unzip xxxx.zip
命令的安装:
sudo apt update
如果ping www.baidu.com 不通,先不管
sudo apt install xxxx ---> xxxx为相关的命令
1. /bin目录
该目录下存放所有用户都可以使用的、基本的命令。
ls cd
如何查看命令
which xxx
2. /sbin 目录
该目录下存放系统命令,即只有管理员能够使用的命令。
3. /dev目录
该目录下存放的是设备文件,设备文件是Linux中特有的文件类型.
ls * -ltr
* : 代表当前目录下的所有文件
c : char 字符设备文件
b : block 块设备文件
l : link 链接文件
4./etc目录
该目录下存放着各种配置文件。
sudo /etc/init.d/networking restart
sudo /etc/init.d/xxx start
stop
restart
5./lib目录
该目录下存放共享库和可加载(驱动程序),
共享库用于启动系统。运行根文件系统中的可执行程序,
比如:/bin /sbin 目录下的程序。
6、/home目录
用户家目录,它是可选的,对于每个普通用户,
在/home目录下都有一个以用户名命名的子目录,
里面存放用户相关的配置文件。
7./root目录
(管理员)超级用户的目录,与此对应,
普通用户的目录是/home下的某个子目录。
8./usr目录
/usr目录的内容可以存在另一个分区中,
在系统启动后再挂接到根文件系统中的/usr目录下。里面存放的是共享、只读的程序和数据,
这表明/usr目录下的内容可以在多个主机间共享,
这些主要也符合FHS标准的。
/usr中的文件应该是只读的,
其他主机相关的,可变的文件应该保存在其他目录下,
比如/var。/usr目录在嵌入式中可以精减。
9、 /var目录
与/usr目录相反,/var目录中存放可变的数据,
比如spool目录(mail,news),log文件,临时文件。
10、/proc目录
这是一个空目录,
常作为proc文件系统的挂接点,
proc文件系统是个虚拟的文件系统,
它没有实际的存储设备,里面的目录,
文件都是由内核临时生成的,用来表示系统的运行状态,
也可以操作其中的文件控制系统。
11、 /mnt目录
用于临时挂载某个文件系统的挂接点,
通常是空目录,也可以在里面创建一引起空的子目录,
比如/mnt/cdram /mnt/hda1 。用来临时挂载光盘、硬盘。
mount
12. /tmp目录
用于存放临时文件,通常是空目录,
一些需要生成临时文件的程序用到的/tmp目录下,
所以/tmp目录必须存在并可以访问
三 操作系统
什么是操作系统?
以汽车操作系统为例:
转向系统 方向盘 (接口)
人力转向 不安全 效率低 浪费
机械转向 安全 高效
加油系统 油门 (接口)
导航系统 ....
多子系统相互协调的系统 为了达到一个目的
最终操作的是汽车系统的硬件
计算机的操作系统:
CPU 硬盘 内存 网卡 USB .....
进程管理
管理CPU
内存管理
文件系统
网络设备管理
设备文件的管理
计算机的操作系统 管理计算机 硬件资源 和软件资源 的一款软件
程序和进程的区别?
程序是指令的集合,是放在硬盘上的,静态的
进程是程序运行的实例 进程在内存中,是动态的
程序运行一次产生一个进程,运行多次产生多个进程
接口: 接口的实现者 接口的使用者
C语言的函数实现接口
标准库函数 sprintf printf( ,...) fopen fread fwrite //可变参数
man 3
四 计算机语言的发展史
32位的机器
2^32 种状态 ---> 4G ---> 40多亿
机器语言 0 1
vi hello.c
gcc hello.c
./a.out
echo $? ---> 0 上一条命令的执行结果
echo 字符串 将字符串显示在屏幕上
编译的过程(C语言的处理过程)
1)gcc -E hello.c -o hello.i
预处理:给预处理器下的命令
不参与编译的过程
2) gcc -S hello.i -o hello.s
编译:给编译器下的命令
3) gcc -c hello.s -o hello.o
汇编: 将编译后的文件汇编成汇编文件
4) gcc hello.o
将目标文件和库文件,运行时文件链接生成可执行文件
五 C语言实现大型项目组织
在源文件中实现接口
写一个程序,调用接口
C语言组织工程文件的思想
mkdir Imath
编译检查的是语法错误,一般用户单元测试
编译的基本单位是源程序
nm 命令
后面跟二进制文件,列出.o .a .so 中的符号信息。
函数名 全局变量 静态的局部变量
nm test.o
前面的地址不是可执行文件中的真正的地址,
只是在文件中的偏移地址
U 代表该文件中只有函数的声明,T 代表改文件中有文件的定义
gcc *.o
nm a.out
复制粘贴命令,在视图模式下使用:
yy 复制一行的命令
p 粘贴的命令
ctrl + v + 上下左右的箭头
选中好要复制的区域之后,按y复制
p 粘贴
shift + v + 上下左右的箭头
选中好要复制的区域之后,按y复制
p 粘贴
命令模式下
输入 f ---> 显示文件名
输入 pwd ----> 显示文件所在的目录
删除命令:dd 删除一行
shift + v + 上下左右的箭头
选中好要复制的区域之后,按d 删除
---------------------------------------------------------------------------------------------------------------------------------
Day11
零 建立虚拟机和物理机的共享目录
1. 选择虚拟机 ---》 点击设置
2. 选择选项 ---》 点击共享文件夹
3. 选择总是启用 ---》 点击浏览 添加要共享的目录
4. 选择完成
5. cp /mnt/hgfs/xxxx ./ -rf //由win ---> ubuntu
6. cp xxx /mnt/hgfs/xxxx -rf //由ubuntu ---> win
补充:
查看文件或者目录的大小
du -ch/-sh xxx
一 回忆昨天的内容
1) Unix / Linux系统介绍
2) 基本的Linux命令
ls -a -l -ltr
cd 绝对路径 和 相对路径 . ..
cp -R/-r
tar zcf xvf 压缩和解压的命令
在vim中的拷贝
yy
p
ctrl + v + 上下左右箭头选中 y p
rm 删除 -R / -r
cat 查看文件的内容
vim 编辑器的用法:
视图 esc
编辑 a o
命令 shfit + :
echo $? 查看上一条命令的返回值
nm 查看文件的符号表
3) 操作系统
标准C库函数 为了方便应用程序的编程
fopen man 3
系统调用 为了方便调用操作系统提供的接口
open man 2
Linux 内核
sys_open
4) 计算机语言的发展史
编译的过程
5) C语言实现大型的代码组织
mkdir Imath
gcc *.o
nm test.o --> 看到的只是符号在文件中的偏移
nm a.out --> 看到的是函数的真实的地址
a.out中看到的真实地址是前面的(p_add.o ...)
的地址的重定位,这就叫可重定位。
现在的地址对刚才的地址做了一个重定位,
现在T前面的地址,是将来装载到内存中的实际入口地址,
它已经定死了。
gcc *.o
链接的时候,将所有的.o文件拼接到一起。
链接分两种:
静态链接 和 动态链接
生成可执行文件的时候,链接已经完成了,这叫静态链接。
生成可执行文件的时候,链接发生了,
但是没有链接到实际的代码,
链接实际代码发生在程序运行的时候,这就叫动态链接。
二 静态库的制作和使用
静态库文件的命名规则
lib + 库名.a
步骤:
1.将要加入静态库的文件编译为目标文件
gcc -c *.c
2. 将目标文件添加到静态库
ar -r libImath.a *.o
3. 使用静态库链接生成可执行文件
rm *.o
mv test.c ../
gcc -c *.c
ar -r libImath.a *.o
ar -tf libImath.a ar 和 tar 命令如出一辙
nm libImath.a
cp pmath.h ../
gcc -c test.c
gcc test.o -LImath -l Imath --》 静态链接
./a.out
-L 后面跟路径
-l 后面跟库名
注意: 文件包含的时候注意“” 和 <>
" " ---> 在当前目录下搜索,如果找不到,到系统
指定的目录下找,还找不到,报错
" " 包含可以包含目录或者文件
系统指定的目录在哪里?
/usr/inlcude
......
三 环境变量
什么是环境变量?
环境变量和进程相关,每个进程都有自己的环境变量
进程可以通过环境变量去查找或者访问相关的资源
bash进程的环境变量
如何查看bash进程的环境变量?
env
环境变量的组织格式:
name=value
如何获取指定的环境变量的值?
$name
echo $name //取环境变量的值
如何更改环境变量的值?
name=newvalue
注意:等号的两边不允许出现空格
自定义环境变量
BAIZHI=sunshine
将环境变量导出到环境变量列表中
export BAIZHI
补充:
grep 指定的文件中查找相关的字符串
| 管道 可以用于命令之间
命令(输出) | 命令 (输入)
env | grep "BAIZHI"
在Imath目录下查找p_add字符串:
grep "p_add" -rn
Linux 中有标准输入 标准输出 标准错误输出
键盘 显示器 显示器
PS1 和 PATH 环境变量
PS1 是bash (命令行)的提示符
echo $PS1
env | grep "PS1"
发现echo可以看到它的值,但是env列表中却没有它的值。
export PS1
PS1='\W\$' 修改PS1环境变量的值
Linux系统中 bash 进程启动的时候,会运行一个
脚本程序 ~/.bashrc
vi ~/.bashrc
source ~/.bashrc
PATH环境变量:
:分割多条路径
比如说在执行ls 这个命令的时候,先在第一个路径下
查找,找不到的话,在第二个路径下查找,以此类推,
直到在最后一条路径下查找,都找不到,报错!
mv a.out ls
./ls
ls
注意区分 ./ls 和 ls 的区别
GG:跳转到文件的末尾
gg:跳转到文件的开头
需求: 在执行a.out的时候,不加./
vim ~/.bashrc
export PATH=$PATH:.
四 动态库(共享库)的制作和使用
动态库的命名规则:
lib + 库名.so
步骤:
1. 将要加入动态库的文件编译为与位置无关的目标文件
cd Imath
rm *.o *.a
gcc -fPIC -c *.c
// 加了 -fPIC 之后,生成与位置无关的目标文件
2. 将第一步生成的目标文件打包到动态库
gcc -shared -o libImath.so *.o
3. 使用动态库链接生成可执行文件
gcc -c test.c
gcc -o test.o -LImath -l Imath
a.out 发现报错
报错原因:发生了链接,但是找不到libImath.so这个动态
库文件
链接器报的错
如何确定a.out要依赖哪些库文件?
ldd a.out
ld ---> 链接器
要告诉加载器,要加载的库文件在什么位置?
两种方法:
1. export LD_LIBRARY_PATH=LD_LIBRARY_PATH:Imath
2. 加载器和链接器有一个相同的路径
/usr/lib 或 /lib
直接将动态库文件放到/lib下,即可
cp libImath.so /lib
ldd a.out --> 发现可以找到库文件
a.out
动态库的制作:
编译成与位置无关的目标代码 -fPIC
不加这个命令 编译出来的还是静态库
静态库,每使用一次,都要加载到内存中一份,
而动态库在内存中只有一份副本。
动态库又叫共享库 -shared
还有两个问题需要解决:
1. 什么时运行时文件?
2. 链接时为什么没有加 -lc 也可以链接到?
mv libImath.so /lib
发现 gcc test.c -lImath 也可以编译通过
gcc test.c -lImath -v
类似于 你执行上面这个命令时,报出来的一堆的 .o文件
这些.o 文件都属于运行时文件。
nm /usr/lib/gcc/../../Scrt1.o
D : 是放在数据段的,就是全局变量
U : 函数的声明
T :函数的实现
0000000000000000 T _start
在 _start 函数里面调用了 U main 函数,
这也就是为什么,main函数是一定是入口函数。
_start 是个汇编符号
动态库的特点:
加载到内存中执行的时候,才发生真正的链接
使用静态链接生成的可执行文件,不依赖静态库。
使用动态库链接生成的可执行文件,
发生的是虚的链接,不是真实的链接,
而实际的链接发生在执行阶段,依赖动态库
动态库有利于软件的升级
比如360杀毒软件等,就是利用这个原理。
与位置无关:
共享库中有一个引用计数,引用计数为0时,
动态库从内存中卸载
动态加载在执行之前,不加载到内存中,在内存中的
位置不确定,这就叫与位置无关。