【Linux】基础IO2

重定向

重定向的符号

“>”:清空重定向
“>>”:追加重定向

从内核角度理解重定向

在进程的结构体中,有一个描述进程打开文件的信息的结构体指针(struct file_struct *files;),该结构体指针指向一个结构体(struct file _struct{…}),这个结构体里面有一个结构体(struct file * fd_array[NR_OPEN_DEFAULT]),该结构体保存一个指针数组,可以理解为一个文件描述符表,里面保存的是当前进程打开文件的信息,我们所说的文件描述符就是该指针数组的下标,该指针数组里面保存的指针变量是一个结构体指针(struct file *),该指针指向一个结构体(struct file{…}),这个结构体是描述文件具体信息的。

重定向就是将struct file *这个结构体指针的指向改变成为另外一个struct file结构体。也就是说,从指向某一个文件改变为指向另一个文件。

重定向的接口dup2函数

函数原型:

int dup2(int oldfd, int newfd);

作用:将newfd的值重定向为oldfd,即newfd拷贝oldfd
参数:newfd和oldfd都是文件描述符
执行成功:第一关闭newfd,让newfd指向oldfd对应的struct file*结构体
执行失败:1、如果oldfd是一个非法或者是无效的文件描述符,则重定向失败,newfd没有变化;2、如果oldfd和newfd的值相等,则什么事情都不干。

代码验证:
将标准输出重定向为a.txt文件。

#include <stdio.h>
  2 #include <unistd.h>
  3 #include <fcntl.h>
  4 int main()
  5 {
  6   //让标准输出流指向a.txt文件
  7   int fd =open("./a.txt",O_RDWR | O_CREAT,0664);
  8   if(fd < 0){
  9     perror("fopen");
 10     return 0;
 11   }
 12 
 13   printf("before dup2:hello world\n");
 14 
 15   /*
 16    * oldfd:fd 
 17    * newfd:1  将一号标准输出重定向到fd对应的文件
 18    * 1  要进行指向更新
 19    */
 20   dup2(fd,1);
 21   printf("after dup2:hello world.\n");                                                         
 22   return 0;
 23 }

动态库和静态库

静态库和动态库都是文件,称之为库文件,用来保存程序代码,在编译一个程序的时候,所链接的库都是独立进行编译的,所以库文件可以将代码分模块出来,哪个模块有问题就修改哪个模块。
什么是库?静态库和动态库都是程序代码的集合。一般为了方便将程序提供给第三方使用,就是将程序编写成为库文件提供给第三方使用,优点首先就是不会泄漏公司的源码,其次就是调用者不用关心库文件内部实现,只需要关注如何调用即可。

动态库

特征:

  • Windows系统下:没有前缀,后缀为dll
  • Linux系统下:前缀为lib,后缀为.so

生成:
使用gcc/g++编译器,增加两个命令行参数:-fPIC和-shared,生成动态库的代码当中不需要包含main函数(程序入口函数)。

动态库的生成测试:

hello.h代码:

 #pragma once 
  2 #include <stdio.h>
  3 
  4 void PrintHello();                                                                             
~

hello.c代码:

 #include "hello.h"
  2 void PrintHello(){
  3   printf("exec hello.c:hello world.\n");                                                       
  4 }
~

在这里插入图片描述

动态库的使用测试:

在这里插入图片描述

编译器在进行链接的时候找不到对应函数的实现,所以报错,编译终止。所以我们下面就得告诉编译器对应函数的实现在哪。

在这里插入图片描述

为了解决上面的问题,我们告诉了编译器依赖的动态库是哪一个,但是又出现了新的问题,编译器找不到动态库的路径,于是我们又说明了动态库的路径,所以在使用动态库的时候需要注意下面两点:

编译可执行程序的时候,依赖动态库。
-L[path]:指定动态库所在的路径
-l[动态库的名称,去掉前缀和后缀]:指定编译可执行程序时,依赖的动态库时哪一个。

在这里插入图片描述

现在我们就执行成功啦!完成了动态库的生成和动态库的使用的测试!

在这里插入图片描述

上面我们将mymain所依赖的动态库放到了可执行程序的路径下,可执行程序可以正常执行,但是如果我们将这个动态库从该路径移除呢?

在这里插入图片描述

mymain这个可执行程序已经不能执行了,原因是程序找不到动态库,那都有哪些方法可以解决这个问题呢?

  • 将动态库放到可执行程序的路径下,不过不推荐
  • 配置LD_LIBRARY_PATH,这个环境变量就是动态库的环境变量
  • 放到系统库的路径下:/lib64,不过非常不推荐这样做

我们现在来解决一下上面这个问题,配置一下LD_LIBRARY_PATH这个环境变量。

在这里插入图片描述
在这里插入图片描述

静态库

特征:

  • Windows系统下:没有前缀,后缀为.lib
  • Linux系统下:前缀为lib,后缀为.a

生成:

  • 第一阶段:使用gcc或者g++将源代码编译成为目标程序(.o)
  • 第二阶段:使用ar -rc命令编译目标程序成为静态库

注意:如果直接使用源代码编译是不行的.

代码测试过程和动态库类似,注意命令不同,就不赘述了。

生成可执行程序的过程中需要依赖动态库或者静态库的时候,编译的时候一定要加上-l[库名]

软链接

软链接其实就是目标文件的快捷方式。
生成软链接:ln -s 源文件 软链接文件

在这里插入图片描述

注意事项:

修改软链接文件,源文件也会修改;
删除源文件的时候软链接文件内容会被清空。
源文件如果被删除,软链接文件还在的,如果修改软链接文件,那么会重新建立源文件,重新建立链接关系,所以删除源文件的时候,一定要将软链接文件也一起删除。

硬链接

硬链接是目标文件的替身。
生成硬链接:
ln 源文件 硬链接文件

在这里插入图片描述

硬链接的inode节点和源文件一致,软链接的inode节点和源文件不一致。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值