第一天
1、命令解析器
shell --unix 操作系统
bash --linux 操作系统
这两者的本质都是根据输入的命令调用可执行程序。
在Linux下快捷键Ctrl+Alt+T可以快速打开终端。
2、Linux快捷键
1)命令和路径补齐
tab命令,如有多个则可以双击显示出所有符合的命令
2)主键盘快捷键
①历史命令切换
历史命令: history
向上遍历:Ctrl+p/向上方向键
向下遍历:Ctrl+n/向下方向键
②光标移动
向左:Ctrl+b
向右:Ctrl+f
移动到头部:Ctrl+a
移动到尾部:Ctrl+e
③删除字符
删除光标后面所有字符:Ctrl+d/del
删除光标前边字符:Ctrl+h/空格键
删除光标前的所有内容:Ctrl+u
④清屏
输入clear命令或者快捷键Ctrl+l
3、Linux系统目录结构
1、/ 根目录:根目录是指逻辑驱动器的最上一级目录,根目录在文件系统建立时已被创建
2、/bin :bin是binary的缩写,可执行二进制文件的目录,通常存放经常使用的命令
3、/dev:dev是device(设备)的缩写,存放linux系统下的设备文件,访问该目录下的某个文件就相当于访问某个设备
4、/etc:存放所有的系统管理所需要的配置文件和子目录
5、/home:用户的主目录,在linux下每个用户都有自己的目录,~表示家目录
6、/lib:系统使用的函数库的目录,存放系统最基本的动态链接共享库
7、/media:linux系统会自动识别一些设备,例如U盘,光驱等等,linux会把识别的设备挂载到这个目录下
8、/mnt:系统提供该目录为了让用户临时挂载别的文件系统
9、/root:系统管理员root的家目录
10、/usr:应用程序和文件的存放目录,类似于windows下的program files
4、用户目录
1、绝对路径:从根目录开始写例如:/home/ahdai/hello
2、相对路径:相对于当前工作目录而言
. 当前目录
.. 上一级目录
- 如果想在最近两个目录进行切换直接输入命令cd -即可
3、ahdai@ubuntu:~$
ahdai:当前登录用户
ubuntu:主机名
~:用户的家目录
$:普通用户
#:超级用户root
5、文件和目录操作
1、查看目录
1)tree 树状列出目录及文件
2)ls :
ls查看该目录下所有子目录和文件
ls -a查看隐藏文件
ls -la 查看详细信息
2、在目录之间切换
cd 目录名:进入该目录
回到家目录的三种方式:
① cd /home/ahdai
② cd ~
③ cd
查看当前所在目录:pwd
3、创建目录
mkdir hello:创建单级目录
mkdir hello/hello1/hello2 -p:创建多级目录
4、删除空目录:rmdir hello //只能删除空目录
5、创建新文件:touch hello //若文件存在则修改时间
6、删除操作
① 删除目录:rm -r hello//-r 表示递归删除目录
② 删除文件:rm hello
7、拷贝文件:cp hello.c hello1.c//把hello.c的内容拷贝到hello1.c中
拷贝目录:cp hello/ newhello -r //目录如果存在则放到该目录下
8、查看文件内容
① cat hello.c
② more hello.c
③ less hello.c//②和③回车查看下一行,空格查看下一页,退出:q/Ctrl+c
④ head hello.c//查看前10行
⑤ tail hello.c //查看后10行
9、创建软连接:
ln -s /home/ahdai/hello/hello.c soft 相当于快捷方式,一旦hello.c被删除软连接则不可用,软连接是产生一个特殊的文件来指向另一个文件,可以适用于目录。创建软连接时必须使用绝对路径
10、创建硬链接:
ln hello.c hard 是一种映射,硬连接数加一,但是硬链接既不能跨文件系统也不能链接目录
6、文件权限,用户、用户组
1、查看当前登录用户:whoami
2、修改文件权限:命令之前都需要加sudo
1)文字法
chmod [who] [+]/[-] [mode]
who:① 文件所有者:u ② 文件所属组:g ③ 其他人:o ④ 所有人:a
+:添加权限 -:减少权限 =:覆盖权限
mode: r :读 w : 写 x : 执行
2)数字法
-:没有权限
r : 4 w : 2 x : 1
3、改变文件或目录所有者或所属组:命令前sudo
chown 新的所有者 文件名
4、更改文件或目录所属的组:chgrp 新的文件组 文件名
7、文件查找和检索
1、通过文件名查找:find + 目录 + -name + "文件的名字" //可以使用*通配符
2、通过文件大小查找: find + 目录 + -size + +10k//大于10k //必须是小写的k大写的M
3、通过文件的类型查找: find + 目录 + -type + d/f/b/c/s/p/l //目录/普通文件/块设备/字符设备/套接字/管道/连接符号
4、按文件内容查找:grep + -r + "查找的内容" + 路径
8、软件的安装和卸载
1、在线安装:sudo apt-get install vim
移除:sudo apt-get remove vim
2、deb包安装:sudo dpkg -i vim.deb
移除:sudo dpkg -r vim
9、U盘的挂载和卸载
1、挂载:系统默认挂载在/media
手动最好挂载在/mnt
查看设备名:sudo fdisk -l
挂载方式: mount + 设备名 + /mnt
2、卸载
sudo umount /media /ahdai/ESD-USB
sudo umount /mnt
第二天
1、压缩包管理
1、gizp----gz格式:
压缩:gizp 文件名 解压缩:gunzip
2、bzip2----bz2格式:
压缩:bzip2 - k 文件名 //保留源文件 解压缩:bunzip2
3、tar
参数:c : 压缩 x : 解压缩 v : 显示提示信息 f : 提示压缩文件的名字
z : 使用gzip方式压缩文件 --- .gz
j : 使用bip2的方式压缩文件 --- .bz2
//如果不加z或者j只打包不压缩
压缩:
1、tar + zcvf + 压缩包名字.tar.gz + 文件
2、tar + jcvf + 压缩包名字.tar.bz2 + 文件
解压缩:
1、tar + zxvf + 压缩包//tar.gz
2、tar + jxvf + 压缩包//tar.bz2
3、解压到指定目录:-C 压缩的目录 //大写
4、rar
参数: a : 压缩 x : 解压缩
压缩:
rar + a + 压缩包名字 + 文件或目录
解压缩:
rar + x + 压缩文件名或目录
5、zip
参数: 如果需要压缩目录需要 -r
压缩:zip + 压缩包名字 + 文件或目录
解压缩:
unzip + 压缩包名字
unzip + 压缩包名字 + -d + 解压目录
2、进程管理
1、查看当前在线用户的情况 who
2、查看整个系统内部所有的进程:ps aux
a : 当前系统所有进程
u : 查看进程所有者和信息
x : 显示没有控制终端的进程//不能与用户进行交互的进程
查询某一些进程:
ps aux | grep xxx 使用管道
3、终止进程:kill
1)查看信号编号:kill -l
2)杀死进程:kill + -信号序号 + pid
4、任务管理器:top
3、网络管理
1、获取网络接口配置信息,修改配置:ifconfig
2、测试与目标主机是否联通:ping
3、查看服务器域名对应的IP地址:nslookup www.taobao.com
4、ftp服务器搭建
vsftpd:文件的上传与下载
1、服务器端:
1)修改配置文件:/etc/vsftpd.conf
2)重启服务:sudo service vsftpd restart
2、客户端:
1)实名用户登录
ftp + IP
输入用户名
输入密码
文件的上传和下载:
上传:put file
下载:get file//不能操作目录,如果需要操作目录,则需对目录进行打包
2)匿名用户登录
ftp + IP
用户名:anonymous//固定
密码:回车
//如果不想让匿名用户在任意目录切换,只需要在ftp服务器上创建一个匿名用户的根目录
3、lftp客户端登录ftp服务器
登陆服务器:
1)lftp + IP
2)login
① lftp username@127.0.0.1
② 输入服务器密码
3)命令:
put :上传文件
mput : 上传多个文件
get : 下载文件
mget :下载多个文件
mirror -R:上传整个目录
mirror :下载整个目录
5、nfs服务器搭建
nfs允许网络中的计算机通过TCP/IP网络共享资源
1、服务器端安装:sudo apt-get install nfs-kernel-server
1)创建共享目录
mkdir hello
2)修改配置文件
vi /etc/export
增加: /home/ahdai/share *(ro(只读),rw(读写))
3)重启服务:sudo service nfs-kernel-server restart
2、客户端
客户端访问共享目录:sudo mount + IP:共享目录名
6、ssh服务器
1、服务器端:
安装:sudo apt-get install openssh-server
2、客户端
1)远程登录:ssh userName@IP(server)
2)退出登录:logout
7、scp命令
超级拷贝:
scp -r 目标用户名@目标主机IP:/目标文件绝对路径/保存到本地绝对(相对)路径
8、其他命令
1、man man 查看手册,一共9章
2、echo:在屏幕上显示字符串
9、关机命令
1、poweroff:关闭电源
2、shutdown:调用init 0
3、halt:关闭OS电源还在工作
4、reboot//重启
10、用户管理
1、创建用户:
sudo adduser + 用户名//需要重新设置密码
sudo useradd -s /bin/bash -g ahdai -d /home/ahdai -m ahdai//用户名可大写
2、设置用户组:
sudo groupadd ahdai
3、删除用户:
sudo deluser + 用户名
sudo userdel -r ahdai //-r:把用户主目录一起删除
4、切换用户:su ahdai
5、root用户:sudo su
6、设置密码:sudo passwd + 用户名
7、退出当前用户:exit
8、当前系统当前用户信息:vi /etc/passwd
第三天
1、vim编辑器的使用
1、命令模式下操作:
1)光标的移动
左:h 下 : j 上 :k 右 :l
行首 :0 行尾:$ 文件开始位置:gg 文件末尾:G
行跳转:行号+G
2、删除操作
删除光标后的字符:x
删除光标前的字符:X
删除单词:dw//光标要移到单词的开始位置
删除光标到行首的字符串:d0
删除光标到行尾的字符串:d$
删除光标当前行:dd
删除多行:ndd
删除==剪切
3、撤销操作
撤销:u 反撤销: ctrl + r
4、复制粘贴
复制:yy
复制多行:nyy
粘贴:p(光标所在下一行)
P(光标所在行)
5、可视模式:v
选择内容:h j k l
复制:y 删除 :d
6、查找操作
1) ./hello
2) ?/hello
3) 把光标移到查找的单词上,按#
7、 缩进
向右:>>
向左:<<
8、分屏操作
1)水平分屏 sp(当前文件不用加文件名, 其他文件需要绝对路径)
2)垂直分屏vsp
快捷键 ctrl + w连按两次w进行换屏操作
2、gcc编译器
1、gcc的工作流程
gcc hello.c -o hello
./hello
如果当前目录下没有头文件,则需要指定头文件目录
gcc hello.c -l + 绝对路径 + -o hello
编译时指定宏
gcc hello.c -l + 绝对路径 + -o hello -D DEBUG
2、gcc的参数
-c 只执行预处理、编译、汇编,生成 .o文件
-S 只执行预处理和编译,生成 .s文件
-E 只执行预处理不生成文件,需要重定向到一个输出文件中
-o 生成文件的名字
-l 头文件路径
-D 宏
-g 添加gdb调试信息
-Wall 警告信息
- O(1,2,3)优化代码
3、静态库的制作
1、命名规则
例如:libmytest.a
2、制作步骤
1)生成对应.o的文件
2)将生成的.o文件打包 ar rcs + libmytest.a + *.o
3)调用静态库 gcc hello.c lib/libmytese.a -o hello -l /include
3、发布和使用静态库
1)发布静态库
2)头文件
4、优缺点
1)优点:
① 寻址方便,速度快
② 库被打包到可执行程序中,直接发布可执行程序即可使用
2)缺点
① 库在可执行程序文件中,因此体积较大
② 如果静态库变了,需要重新编译程序
4、动态库的制作
1、命名规则
例如:libmytest.so
2、制作步骤
1)生成与位置无关的代码//.o
2)将.o打包成动态库
gcc -shared -o libmytest.so *.o -l /include
3)调用动态库
gcc hello.c lib/libmytest.so -o hello -l /include
4)ldd查看所需要的所有动态库:ldd hello
5)系统调用动态库是要根据环境变量来查找的
3、发布和使用动态库
4、解决程序执行中动态库无法被加载的问题
1)放到系统库目录中 //有可能造成与系统目录重名,不能使用
2)临时测试
环境变量:LD_LIBRARY_PATH=动态库中的路径设置给该变量
将设置的值导入到系统环境变量中:export LD_LIBRARY_PATH=动态库中的绝对路径
当终端关闭,设置会失效
3)永久设置//不常用
在家目录下的.bashrc文件中添加export LD_LIBRARY_PATH=动态库目录的绝对路径
.bashrc修改完成需要重启终端
4)
① 需要找动态连接器的配置文件 /etc/ld.so.conf
② 动态库的路径写到配置文件中 //绝对路径
③ 更新 sudo ldconfig -v
5、优缺点
1)优点:
① 执行程序体积小
② 库更行,不需要编译程序
2)缺点
① 需要把动态库也发不出去
② 加载速度相对较慢
5、gdb调试
gdb常见命令
l :从第一行开始列出源码
break n:在第n行设置断点
info break:查看断点信息
run :运行程序
next:单步执行
continue:继续执行
print 变量:打印变量的值
bt :查看堆栈
finish: 退出函数
shell 命令行:执行shall 命令
info program :查看程序是否在运行,进程号,被暂停的原因
clear 行号:清楚断点
step:单步调试进入函数
display :追踪变量
undisplay:取消追踪
gdb调试多进程
set follow-fork-mode parent/child
如果想设置调试指定的进程可以设置条件断点
条件断点:break n if n=3
第4天
1、makefile编写
1、makefile的规则:
三要素:目标、依赖、命令
2、makefile中的三个自动变量
$<依赖中的第一个元素
@target
$^依赖中所有元素
简单的makefile
1 app:main.o add.o sub.o mul.o div.o
2 gcc main.o add.o sub.o div.o mul.o -o app
3 main.o:main.c
4 gcc -c main.c
5 add.o:add.c
6 gcc -c add.c
7 mul.o:mul.c
8 gcc -c mul.c
9 sub.o:sub.c
10 gcc -c sub.c
11 div.o:div.c
12 gcc -c div.c
升级版
1 obj=main.o add.o sub.o mul.o div.o
2 target=app
3 $(target):$(obj)
4 gcc $(obj) -o $(target)
5 %.o:%.c
6 gcc -c $< -o $@
7 clean:
8 rm $(obj) $(target)
9 hello:
10 echo "hello makefile"
2、系统IO函数
1、open函数
int open(const char * pathname, int flags, mode_t mode);
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:读写
O_CREAT:若打开的文件不存在则自动创建该文件
O_TRUNC:若文件存在并以可写的方式打开时,会使文件长度为0原来文件中的资料会消失
O_APPEND:以追加的方式打开文件
O_EXCL:如果O_CREAT也被设置,此指令回去检查文件是否存在做不存在则创立,否则打开错误
open最后一个参数为设置文件权限
1 #include<stdio.h>
2 #include<sys/types.h>
3 #include<sys/stat.h>
4 #include<fcntl.h>
5 #include<stdlib.h>
6 #include<unistd.h>
7 int main()
8 {
9 int fd;
10 fd = open("bucunz",O_CREAT|O_RDWR,0664);
11 if(fd == -1)
12 {
13 perror("open file");
14 exit(1);
15 }
16 int ret = close(fd);
17 printf("ret = %d\n",ret);
18 if(ret == -1)
19 {
20 perror("close file");
21 exit(1);
22 }
23 return 0;
24 }
2、read、write函数
1)read: ssize_t read(int fd, void * buf, size_t count);
函数说明:read()会把参数fd所指的文件传count个字节到buf指针所指的内存中
返回值:返回值为实际读取到的字节数,如果返回0,表示到达文件尾。
2)write: ssize_t write(int fd, const void *buf,size_t count);
函数说明:write()会把参数buf所指的内容写入count字节到所指的文件中
返回值:顺利则会返回实际写入字节数,错误返回-1
1 #include<stdio.h>
2 #include<sys/types.h>
3 #include<sys/stat.h>
4 #include<fcntl.h>
5 #include<stdlib.h>
6 #include<unistd.h>
7 int main()
8 {
9 int fd = open("hello",O_RDONLY);
10 if(fd == -1)
11 {
12 perror("open file");
13 exit(1);
14 }
15 int fd1 = open("newfile",O_CREAT | O_WRONLY,0664);
16 if(fd1 == -1)
17 {
18 perror("open file");
19 exit(1);
20 }
21 //read
22 char buf[1024]={0};
23 int count = read(fd, buf, sizeof(buf));
24 if(count == -1)
25 {
26 perror("read");
27 exit(1);
28 }
29 //write
30 while(count)
31 {
32 int ret = write(fd1, buf, count);
33 printf("write bytes %d\n",ret);
34 count = read(fd, buf, sizeof(buf));
35 }
36 close(fd);
37 close(fd1);
38 return 0;
39 }
第五天
1、lseek函数
off_t lseek(int fd, off_t offset, int whence);
SEEK_SET:将指针指向文件头后再增加offset个位移量
SEEK_CUR:以目前的光标位置往后增加offset个位移量
SEEK_END:将光标指向文件尾后再增加offset个位移量
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<sys/stat.h>
5 #include<fcntl.h>
6 #include<sys/types.h>
7 int main()
8 {
9 int fd = open("aa",O_RDWR);
10 if(fd == -1)
11 {
12 perror("open file");
13 exit(1);
14 }
15 int ret = lseek(fd, 0, SEEK_END);
16 printf("file length = %d\n",ret);
17 //文件拓展
18 ret = lseek(fd ,2000, SEEK_END);
19 printf("return value %d\n",ret);
20 //拓展需要做一次写操作
21 write(fd, "a", 1);
22 close(fd);
23 return 0;
24 }
stat函数和lstat函数
int stat(const char *file_name, struct stat *buf);
函数说明:通过文件名获取filename文件信息,并保存在所指的结构体stat中
返回值:成功返回0,失败则返回-1
下面代码则实现了查看文件大小的命令
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<sys/types.h>
4 #include<sys/stat.h>
5 #include<time.h>
6 int main(int argc, char *argv[])
7 {
8 if(argc < 2)
9 {
10 printf("./a,out filename");
11 exit(1);
12 }
13 struct stat st;
14 int ret = stat(argv[1], &st);
15 if(ret == -1)
16 {
17 perror("stat ");
18 exit(1);
19 }
20 int size = (int)st.st_size;
21 printf("file size= %d\n",size);
22 return 0;
23 }
区别:stat函数追踪函数相当于软链接
lstat函数则不追踪,显示输入文件本身信息
unlink函数
int unlink(const char* pathname);
函数说明:unlink可以从文件系统中删除一个指定名字的文件
返回值:成功返回0,失败则返回-1
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<fcntl.h>
4 #include<stdlib.h>
5 #include<sys/types.h>
6 int main()
7 {
8 int fd = open("tempfile",O_CREAT | O_RDWR, 0644);
9 if(fd == -1)
10 {
11 perror("open file ");
12 exit(1);
13 }
14 //删除临时file
15 int ret = unlink("tempfile");
16 write(fd, "hello\n", 6);
17 lseek(fd, 0 ,SEEK_SET);
18 char buf[24]={0};
19 int len = read(fd, buf, sizeof(buf));
20 write(1, buf, len);
21 close(fd);
22 return 0;
23 }
在执行unlink函数之后仍然可以读到文件中内容,但是执行程序之后,文件被删除。
opendir函数和readdir函数
opendir:DIR *opendir(const char name);
函数说明:opendir()用来打开参数name指定的目录,并返回DIR形态的目录流。
readdir:struct dirent *readdir(DIR *dir);
函数说明:readdir()返回参数dir目录流的下个目录进入点
下面代码功能是计算目录下有多少文件
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<dirent.h>
5 int get_file_count(char *root)
6 {
7 DIR* dir;
8 struct dirent *ptr = NULL;
9 int total = 0;
10 char path[1024];
11 dir = opendir(root);
12 if(dir == NULL)
13 {
14 perror("opendir ");
15 exit(1);
16 }
17 while((ptr = readdir(dir)) != NULL)
18 {
19 if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0)
20 {
21 continue;
22 }
23 if(ptr->d_type == DT_DIR)
24 {
25 sprintf(path, "%s/%s", root,ptr->d_name);
26 total += get_file_count(path);
27 }
28 if(ptr->d_type == DT_REG)
29 {
30 total ++;
31 }
32 }
33 closedir(dir);
34 return total;
35 }
36 int main(int argc, char **argv)
37 {
38 if(argc < 2)
39 {
40 printf("./a.out dir");
41 exit(1);
42 }
43 int total = 0;
44 total = get_file_count(argv[1]);
45 printf("%s has file numbers = %d\n",argv[1], total);
46 return 0;
47 }
48
dup函数和dup2函数
dup:int dup(int fd);
下面代码则使buf和buf1都写入文件中,成功验证了dup函数可以复制文件描述符
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<fcntl.h>
6 int main()
7 {
8 int fd = open("a.txt", O_RDWR);
9 if(fd == -1)
10 {
11 perror("open ");
12 exit(1);
13 }
14 printf("file open fd = %d\n",fd);
15 int ret = dup(fd);
16 if(ret == -1)
17 {
18 perror("dup ");
19 exit(1);
20 }
21 char *buf = "hello dup";
22 char *buf1 = "hello ubuntu linux";
23 write(fd, buf, strlen(buf));
24 write(ret, buf1, strlen(buf1));
25 close(fd);
26 return 0;
27 }
dup2:int dup2(int fd, int fd 2);
下面代码实现了由fd指向a.txt到指向b.txt
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<sys/types.h>
5 #include<unistd.h>
6 #include<fcntl.h>
7 int main()
8 {
9 int fd = open("a.txt",O_RDWR);
10 if(fd == -1)
11 {
12 perror("open ");
13 exit(1);
14 }
15 int fd1 = open("b.txt",O_RDWR);
16 if(fd1 == -1)
17 {
18 perror("open ");
19 exit(1);
20 }
21 printf("fd = %d\n",fd);
22 printf("fd1 = %d\n",fd1);
23 int ret = dup2(fd1, fd);
24 if(ret == -1)
25 {
26 perror("dup2 ");
27 exit(1);
28 }
29 printf("current fd = %d\n",ret);
30 char *buf = "hello world";
31 write(fd, buf, strlen(buf));
32 write(fd1, "hello,linux\n",12);
33 close(fd);
34 close(fd1);
35 return 0;
36 }
fcntl函数
fcntl:int fcntl(int fd, int cmd, long arg);
函数说明:fcntl()针对文件描述符提供控制修改文件参数
F_DUPFD:复制文件描述符
F_GETFD:获取文件描述符标志
F_SETFD:设置文件描述符标志
F_GETFL:获取文件状态标志
F_SETFL:设置文件状态标志
下面代码成功实现了由开始文件的只写,转变到追加
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<fcntl.h>
4 #include<unistd.h>
5 #include<string.h>
6 int main()
7 {
8 int fd;
9 int flag;
10 char *p = "hello world";
11 char *q = "hello linux";
12 fd = open("a.txt",O_WRONLY);
13 if(fd == -1)
14 {
15 perror("open ");
16 exit(1);
17 }
18 if(write(fd, p, strlen(p)) == -1)
19 {
20 perror("write ");
21 exit(1);
22 }
23 flag = fcntl(fd, F_GETFL, 0);
24 if(flag == -1)
25 {
26 perror("fcntl ");
27 exit(1);
28 }
29 flag |= O_APPEND;
30 if(fcntl(fd, F_SETFL, flag) == -1)
31 {
32 perror("fcntl -- append write");
33 exit(1);
34 }
35 if(write(fd, q, strlen(q)) == -1)
36 {
37 perror("write again");
38 exit(1);
39 }
40 close(fd);
41 return 0;
42 }