LinuxC/C++编程(6)—重定向、管道重定向

        LinuxC中的重定向功能,必须依靠等位文件描述符函数dup,该函数的介绍如下:

        dup和dup2用来复制文件描述符。

函数介绍:

#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd,int newfd);

        dup用来复制oldfd所指的文件描述符。但复制成功时返回最小的尚未被使用的文件描述符。若有错误则返回-1,错误代码存入errno中。返回的新文件描述符和参数oldfd指向同一个文件,共享所有的锁定,读写指针,和各项权限或标志位。

        dup2可以用参数newfd指定新文件描述符的数值。若newfd已经被程序使用,系统就会将其关闭以释放该文件描述符;若newfd与oldfd相等,dup2将返回newfd,而不关闭他。dup2调用成功返回新的文件描述符,出错则返回-1。


       标准输入(stdin),标准输出(stdout),标准出错信息(stderr)的文件号分别为0,1,2。


       例如,使用了dup(newfd, 1)后,控制台输出的信息会全部被输出到文件描述符newfd所对应的文件上,而控制台不再输出信息,因为控制台所对应的文件描述符已经被关闭了。

       下面的这句Bash指令:

#ls -l >> /home/lin/桌面/test

可以用这样的C++代码来实现
//============================================================================
// Name        : DupTest.cpp
// Author      : Lin
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <string>
#include <fcntl.h>
#include <unistd.h>
using namespace std;

int main()
{
	string path = "/home/lin/桌面/test"; //把标准输出流重定向到这个文件中
	int newFd = open(path.c_str(), O_RDWR|O_CREAT, S_IRWXU);//open和close并不在同一个头文件中,open()在<fcntl.h>
	dup2(newFd, 1);//包含于<unistd.h>
	close(newFd);//包含于<unistd.h>
	execlp("ls", "ls", "-l", NULL);
	//cout << "heiheihei" << endl;//假如加进了这句代码,这个字符串被直接写进path路径的文件立。这句代码和write(STDOUT, str, sizeof(str))是一样的,本质上都是把字符串写进标准输出流所对应的文件描述符STDOUT(即1)中
	return 0;
}

        在Ubuntu下测试通过,和Bash指令的作用一样。


        再来看另一个例子,Linux下的管道重定向,例如下面的这句Bash指令:

# ls -l | wc

        这个指令的作用是,把ls的输出作为wc的输入,最后wc的结果输出到控制台上。

        这个指令,用C代码的实现思路是这样的,构造一个管道,把标准输出流挂到管道的写入端上,标准输入流挂到管道的读取端上,工作流程如下:

ls -l的结果 --> STDOUT(即管道的写入端)--> STDIN(即管道的读取端)--> 作为wc的输入 --> 最后的结果打印到控制台上。


这里直接贴代码了:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    int pfds[2];
    char *path = "/home/lin";
    chdir(path);

    if ( pipe(pfds) == 0 ) {

    if ( fork() == 0 ) {

        close(1);
        dup2( pfds[1], 1 );//标准输出流挂到管道写入端
        close( pfds[0] );
        execlp( "ls", "ls", "-l", NULL );

    } else {

        close(0);
        dup2( pfds[0], 0 );//标准输入流挂到管道读取端
        close( pfds[1] );
        execlp( "wc", "wc", NULL );

    }

    return 0;
    }
}

同样Ubuntu下测试通过,作用和Bash指令一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值