Linux基础

第一天

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 }


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值