首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Linux:基础IO(一.C语言文件接口与系统调用、默认打开的文件流、详解文件描述符dup2系统调用

()、write()、read() 5.文件描述符 5.1 0、1、2 5.2底层 6.文件描述符的分配规则 重定向—dup2()系统调用 7.Linux中一切皆文件 1.基础认识 文件是存储磁盘或其他存储介质上的数据集合...char* str = "this's test.txt"; fputs(str, f); fclose(f);//关闭 return 0; } 以w方式打开时,文件首先会被清空,这也就是为什么我们看不到新的一个...那这就说明OS一定提供了相关的系统调用接口 4.相关系统接口 4.1open() 2号手册,说明是系统调用接口 open 函数是用于打开文件的系统调用函数。...,而且新打开的test.txt文件的fd为1,代替了标准输出流的位置,printf就向test.txt中写入了 重定向—dup2()系统调用 dup2() 是一个系统调用,用于复制文件描述符。...它的原型如下: #include int dup2(int oldfd, int newfd); dup2() 系统调用的作用是将 oldfd 文件描述符复制到 newfd 文件描述符

14710

【Linux】开始了解重定向

那么创建的文件描述符很自然的就使用了3! 那么加入我们关闭012中的文件呢,那么新打开的文件描述符会是3吗???...以往的 printf fprintf都是先讲内容写到语言级的缓冲区里写到文件内核缓冲区了,所以fflush作为一个系统调用,就是刷新文件内核缓冲区,使其输出到文件中!!!...而为什么不加入fflush 呢结果是log.txt文件里也什么都没有呢??? 就是因为内容写入到文件内核缓冲区里还没有刷新就被close关闭了,所以还没刷新就文件关闭了,还怎么打印到文件中。...为什么会有两个缓冲区, **因为系统调用是有成本的!...现象 2 : 按理说我们fork()之后,创建了子进程,子进程会继承父进程的代码与数据。那么为什么显示器只打印了一遍呢???

7410
您找到你想要的搜索结果了吗?
是的
没有找到

【Linux】基础IO_文件描述符与重定向

通过文件描述符,也就是该进程对应的的文件描述符表所对应的下标。就可以找到该进程所打开的各个文件。 我们再来看如下现象: 为什么文件描述符是从3开始的呢?...这也是为什么我们打开文件时,返回的文件描述符是从3开始,因为前面的0 1 2已经被占用了 一个文件可以同一个进程中被打开对此,也就意味着不同的文件描述符,可能会指向同一个文件。...,但是我们关闭1号文件描述符对应的文件后,会发生什么呢?...所以假如我们要将1号文件描述符的指向的文件修改为fd对应的文件,应该这样来写:dup2(fd,1),这就是输出重定向,当然输入重定向就是:dup2(fd,0)。...dup2原理: dup2函数的原理实际上就是通过拷贝的方式,修改原来文件描述符表中特定下标所指向的文件,这里需要注意一点的是,dup2函数实现重定向时,会先将原有的文件描述符指向的对应的文件关闭,这样避免内存泄漏问题的出现

21030

【Linux】基础IO_文件描述符

通过文件描述符,也就是该进程对应的的文件描述符表所对应的下标。就可以找到该进程所打开的各个文件。 我们再来看如下现象: 为什么文件描述符是从3开始的呢?...这也是为什么我们打开文件时,返回的文件描述符是从3开始,因为前面的0 1 2已经被占用了 一个文件可以同一个进程中被打开对此,也就意味着不同的文件描述符,可能会指向同一个文件。...,但是我们关闭1号文件描述符对应的文件后,会发生什么呢?...所以假如我们要将1号文件描述符的指向的文件修改为fd对应的文件,应该这样来写:dup2(fd,1),这就是输出重定向,当然输入重定向就是:dup2(fd,0)。...dup2原理: dup2函数的原理实际上就是通过拷贝的方式,修改原来文件描述符表中特定下标所指向的文件,这里需要注意一点的是,dup2函数实现重定向时,会先将原有的文件描述符指向的对应的文件关闭,这样避免内存泄漏问题的出现

1.1K30

Linux之基础IO

,默认是在当前路径下对该文件进行访问; 当我们把fopen,fclose,fread,fwrite等接口写完之后,代码编译形成二进制可执行程序后,还没有运行的情况下,文件对应的操作有没有起作用?...访问文件时,是用底层的open系统调用接口,它访问文件需要用到文件描述符C语言中,我们访问文件用的是FILE而不是文件描述符,因此可以推测出,FILE中必定有一个文件描述符的字段。...2.理解 为什么文件描述符是0,1,2,3……这些整数?它的本质是什么? 文件描述符的本质是数组的下标。...文件描述符是如何进行分配的呢? 要关闭fd对应的文件,需要调用close,即close(1)就是关闭fd = 1对应的文件。...2.接口 dup2dup2的作用是两个文件描述符之间进行拷贝(拷贝的不是文件描述符本身,而是它们文件描述符表中所对应的文件指针) dup2的参数中oldfd和newfd,dup2一旦重定向后

17030

Linux重定向及缓冲区理解

文件描述符:1 stderr   标准错误                   文件描述符:2 接下来仔细观察下面代码:  解释:先关闭默认打开的标准输出文件,再打开一个文件命名为log.txt,...可以发现,原本要打印显示器上的内容竟然神奇地打印到了文件里!!!为什么???...解释原因: 当一开始关闭标准输出后,文件描述符1就被空了出来,再打开新的文件,新文件被分配的文件描述符就是1,c语言的printf内部实际是往stdout中打印,fprintf也指定了是往stdout中打印...dup2接口:         接下来介绍一个重定向的重要接口dup2,先查一下手册: 简单来说它的功能就是: 将文件描述符表下标为oldfd的内容拷贝到文件描述符下标为newfd的内存中,我们用dup2...运行结果: 因为之前没关1文件,所以它被分配的文件描述符是3,但我们用dup2改变了文件描述符下标为1的内容,将它的内容改为和下标为3的内容一样,做到了重定向; 缓冲区:         在上一篇文件系统中我讲到

6910

【Linux修炼】12.深入了解系统文件

我们的C语言的这批接口封装了系统的默认调用接口。同时C语言的FILE结构体也封装了系统的文件描述符。 那为什么是0,1,2,3,4,5……呢?..._array[]的指针数组,因此如图前三个0、1、2被键盘和显示器调用,这也就是为什么之后文件描述符是从3开始的,然后将文件的地址填入到三号文件描述符里,此时三号文件描述符就指向这个新打开的文件了。...再把3号描述符通过系统调用给用户返回就得到了一个数字叫做3,所以一个进程访问文件时,需要传入3,通过系统调用找到对应的文件描述符表,从而通过存储的地址找到对应的文件文件找到了,就可以对文件进行操作了...什么是重定向 对于上面的例子,我们关闭文件描述符0和2对应的文件吗,那么如果关闭1呢?...2. dup2 系统调用的重定向 在上面演示的无论是分配规则还是重定向,直接以close关闭的操作非常的挫,因为这样的close操作不够灵活,所以现在介绍一个系统调用的重定向接口:dup2 int dup2

39100

六.Linux管道及重定向

那么, 子进程中,先调用dup2(fd[0],0);此函数就是将标准输入的文件描述符 0,指向了管道的读端。...假设此时管道读端的文件描述符为 3、写端文件描述符为 4 。...调用dup2(fd[0],0),实际上就是将文件描述符 3 指向的文件表项赋值给了文件描述符 0,而文件描述符 0 正是进程默认的标准输入。...调用dup2(fd[0],0)之后还需要调用close()函数将管道原有的文件描述符关闭关闭的意思是文件描述符 3 和 4 不再索引到管道或者其他文件,也就是说此时使用 read 函数从文件描述符 3...完成管道的设置之后,就可以通过 exec 族函数来执行外部命令了。需要注意的是,调用 exec 族函数并不会把管道这种 IPC 资源覆盖或者重新初始化。

2.3K20

我们天天都在使用的管道命令,Shell 在里面到底动了什么手脚?

可以将进程看成一个带壳的球体,exec 之后,外面的壳不会变,球里面的东西被完全替换了。而输入输出文件描述符默认壳上面,这意味着指令 cmd 的输入输出继承了 shell 进程的输入输出。...pipe 管道用于父子进程的通信, fork 之前创建 pipe,pipe将成为 fork 之后父子进程之间的纽带。...dup2 下面我们就需要调整图中描述符的尖头,将 cmd1 进程的 stdout 描述符指向管道写,将 cmd2 进程的 stdin 描述符指向管道读,这就需要神奇的 dup2(fd1, fd2) 函数...注意平时我们调用 close 方法本质上只是递减引用计数,同一个内核对象是可以被多个进程共享的。当引用计数减到零时就会正式关闭。 ?...下面我们将 dup2 函数的规则应用一下,对两个进程分别调用 dup2 方法得到 ? 然后再将不需要的描述符关闭掉,就得到了下面的终极图,完美! ?

86620

linux c——dup( )和dup2( )函数详解

dup()函数和dup2()函数书上文件操作那一章,已经讲过了,这周看重定向这块,发现它挺重要,就再看了回,记录下。...当复制成功是,返回最小的尚未被使用过的文件描述符,若有错误则返回-1.错误代码存入errno中返回的新文件描述符和参数oldfd指向同一个文件,这两个描述符共享同一个数据结构,共享所有的锁定,读写指针和各项全现或标志位...若参数newfd已经被程序使用,则系统就会将newfd所指的文件关闭,若newfd等于oldfd,则返回newfd,而不关闭newfd所指的文件。...dup2所复制的文件描述符与原来的文件描述符共享各种文件状态。共享所有的锁定,读写位置和各项权限或flags等. 返回值: 若dup2调用成功则返回新的文件描述符,出错则返回-1....”>”)就是通过调用dup或dup2函数对标准输入和标准输出的操作来实现的。

1.4K10

基础IO--重定向&&缓冲区&&stderr

接下来调用 write 接口,向 1 号文件描述符中进行写入,本来 1 号文件描述符对应的是显示器文件,原本向显示器文件中写入的内容,此时就被写入到新打开的文件中,没有向显示器文件中写入,因此屏幕上就不会出现字符串...重定向的本质:是在内核中改变文件描述符表特定下标的内容,和上层无关! 为什么需要fflush函数刷新标准输出缓冲区? 每一个系统中新建的文件都会有方法表和内核文件缓冲区。...理解重定向 #include int dup(int oldfd); int dup2(int oldfd, int newfd); 该函数的作用是将文件描述符 oldfd 复制到文件描述符...该函数返回新的文件描述符 newfd 或者在出错时返回-1。最终剩的是oldfd中的内容。 如果 oldfd 不是一个有效的文件描述符,那么调用失败,newfd 不会被关闭。...如果 oldfd 是一个有效的文件描述符,并且newfd 的值与 oldfd 相同,那么 dup2() 不做任何操作,直接返回 newfd。

6100

详解nohup devnull 2>&1 含义的使用

nohup命令:如果你正在运行一个进程,而且你觉得退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。...该命令的一般形式为:nohup command & ls xxx 1>out.txt 2>&1 nohup /mnt/Nand3/H2000G >/dev/null 2>&1 & 对 于& 1 更准确的说应该是文件描述符...1,而1 一般代表的就是STDOUT_FILENO,实际上这个操作就是一个dup2(2)调用.他标准输出到all_result ,然后复制标准输出到文件描述符2(STDERR_FILENO),其后果就是文件描述符...用strace可以看到: 1. command > file 2>&1 这个命令中实现重定向的关键系统调用序列是: open(file) == 3 dup2(3,1) dup2(1,2)...2. command 2>&1 >file 这个命令中实现重定向的关键系统调用序列是: dup2(1,2) open(file) == 3 dup2(3,1) 为什么要用 /dev/null

2.8K31

linux系统编程之管道(一):匿名管道和pipe函数

一、进程间通信 每个进程各自有不同的用户地址空间,任何一个进程的全局变量另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走...pipe函数调用成功返回0,调用失败返回-1。 开辟了管道之后如何实现两个进程间的通信呢?比如可以按下面的步骤通信。 ?...父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。 2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。 3. 父进程关闭管道写端,子进程关闭管道读端。...管道的读写端通过打开的文件描述符来传递,因此要通信的两个进程必须从它们的公共祖先那里继承管道文件描述符。...上面的例子是父进程把文件描述符传给子进程之后父子进程之间通信,也可以父进程fork两次,把文件描述符传给两个子进程,然后两个子进程之间通信,总之需要通过fork传递文件描述符使两个进程都能访问同一管道,

2K00

文件底层的深入理解之文件输入输出重定向

原因就是该进程的文件描述符表中,原来的下标1位置存的是显示器文件的地址,你使用系统调用接口close(1),相当于把1位置的内容清空了,也就是1位置不再存储显示器文件的地址,后来你又打开了log1.txt...而在上层的语言层面上,stdout这个文件文件描述符仍然为1,而且printf函数只认stdout这个文件,只会往stdout这个文件进行写入,stdout文件通过它的文件描述符底层的文件描述符表中进行查找的时候找到...下面是图解: 但上面这一段代码有一个小细节需要注意,就是你进程结束之前不能关闭文件。...如果在进程结束之前关闭文件,语言层面的缓冲区的内容还来不及刷新到文件文件描述符中1位置的地址就被清空了,最后进程退出要刷新缓冲区的内容时会因为找不到文件的地址而写不到文件当中。...下面我用dup2()这个系统调用接口实现一下输出重定向和输入重定向。

8510

【Linux】 基础IO——文件(下)

文件描述符为什么从3开始使用?...重定向的本质 关闭文件描述符0后,发现从0开始可以被输出了 ---- 关闭文件描述符0和2后,发现0和2都可以被使用了 ---- 进程中,文件描述符的分配规则:文件描述符表中,最小的,没有被使用的数组元素分配给新文件...,这叫做输入重定向 追加重定向 关闭文件描述符1后,导致printf不会打印显示器上,而是追加到log.txt文件中 运行可执行程序,无显示,都追加到log.txt文件中 ---- 重定向函数...——dup2 输入 man dup2 查看 刚刚重定向时,需要先关闭文件描述符1,再打开文件 现在可以直接将文件打开,使用dup2重定向 输出重定向对应的文件描述符是1 打开myfile文件,假设其文件描述符是...时,打印的内容已经缓冲区中被刷新走了,刷新之后fork就没有任何意义了 所以fork就什么也没干 当打印到普通文件时 刷新策略:全缓冲 使用 hello world 没办法把缓冲区写满,就无法刷新,

2.1K30

APUE学习手札 编写一个与3.12节中dup2功能相同的函数,要求不调用fcntl函数,并且要有正确的出错处理

3.2 编写一个与3.12节中dup2功能相同的函数,要求不调用fcntl函数,并且要有正确的出错处理。...思路,不断执行dup函数,直到返回与newfd相同的文件描述符,所有都执行结束之后关闭之前dup返回的文件描述符 不要忘记特判newfd和fd相同的情况,直接返回。...记住dup2还多了一歩先关闭newfd的步骤 #include "apue.h" #define BUFFSIZE 16 int main() { char buffer[BUFFSIZE]; int...编译生成了一个3.2的执行文件,上述代码的功能是复制了STDIN_FILENO和STDOUT_FILENO这两个文件描述符,分别返回4和5 编译生成了一个3.2的执行文件,上述代码的功能是复制了STDIN_FILENO...和STDOUT_FILENO这两个文件描述符,分别返回4和5 再通过读写验证my_dup是否调用成功,出错处理也程序中有体现。

84310

【Linux】文件操作文件描述符重定向缓冲区

文件操作接口的使用 三、文件描述符 1、什么是文件描述符 2、文件描述符的分配规则 四、重定向 1、什么是重定向 2、dup2 系统调用 3、三种重定向的实现 五、Linux 下一切皆文件 六、缓冲区...> # fd:目标文件对应的文件描述符 # int:函数返回值,关闭成功返回0,关闭失败返回-1; 文件打开方式 -文件打开方式 -含义 如果指定文件不存在 O_RDONLY 以只读形式打开 出错 O_WRONLY...(同一个 fd 指向不同的 file 对象) 2、dup2 系统调用 我们可以使用上面 close(1) 的方式实现重定向,但是我们发现先关闭、再打开这种方式非常麻烦,并且如果 0 和 1 号 fd 都被关闭时...的一份拷贝,并且必要时关闭 newfd。...---- 六、缓冲区 1、为什么要有缓冲区 我们之前编写 进度条代码 的时候就提到了缓冲区,而 缓冲区本质上就是一段内存,那么缓冲区是由谁申请的?缓冲区属于谁?以及为什么要有缓冲区呢?

3.8K00

【Linux】基础IO——系统文件IO&fd&重定向&理解

2.read和write 1.write 文件打开和关闭说完之后,自然就是我们的写入接口了 //man 2 write #include //把一个文件描述符输入 ssize_t...---- 四、文件描述符fd 1.引入 看到上面的结果,open的返回值为什么是从3开始的,那0,1,2跑哪里去了呢,而且还是连续的小整数(说到连续,我们想到的是数组下标连续) C语言阶段,我们知道C...访问文件时,底层open必须采用系统调用,而系统调用接口访问文件必须用文件描述符,而在C语言用的并不是文件描述符,而是FILE,所以这个FILE结构体必定有一个文件描述符的字段。...2.接口 dup2的作用是两个文件描述符之间进行拷贝,是把fd里面的内容拷贝,这点是我们需要注意的。...dup2的参数我们需要去格外关注一下:dup2一旦重定向之后,最终剩下的都是oldfd: 下面,我们直接通过dup2重定向把原来显示到显示器的内容却显示到文件里面: 3.追加重定向 无非就是在打开文件的时候不需要清空直接改成追加方式

36220

shell脚本 >devnull 2>&1

拓展mohup命令 nohup命令:如果你正在运行一个进程,而且你觉得退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。...1,而1 一般代表的就是STDOUT_FILENO,实际上这个操作就是一个dup2(2)调用.他标准输出到all_result ,然后复制标准输出到文件描述符2(STDERR_FILENO),其后果就是文件描述符...command 2>&1 >file 2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是终端。>file 后输出才被重定向到file,但标准错误仍然保持终端。...用strace可以看到: 1. command > file 2>&1 这个命令中实现重定向的关键系统调用序列是: open(file) == 3 dup2(3,1) dup2(1,2) 2. command...2>&1 >file 这个命令中实现重定向的关键系统调用序列是: dup2(1,2) open(file) == 3 dup2(3,1) 为什么要用 /dev/null 2>&1 这样的写法.这条命令的意思是将标准输出和错误输出全部重定向到

40910

嵌入式Linux:文件共享

文件描述符复制: 通过多次调用open函数或使用dup()、dup2()函数,可以制造出多个不同的文件描述符,这些描述符指向同一个文件。...1、同一个进程中多次调用 open 函数打开同一个文件 同一个进程中多次调用 open 函数打开同一个文件会得到多个不同的文件描述符(File Descriptor,简称FD)。...每次调用 open 都会返回一个新的文件描述符,这些描述符可以独立地用于对文件的读取、写入等操作。...3、同一个进程中通过 dup(dup2)函数对文件描述符进行复制 同一个进程中,可以使用dup函数或dup2函数来复制文件描述符。...而dup2函数则允许指定新的文件描述符的值,如果指定的文件描述符已经被占用,dup2会先关闭描述符,然后将其重定向到指定的文件

5200
领券