zoukankan      html  css  js  c++  java
  • [Chapter10] 对重定向的理解

    常用的重定向如who->userlist.txt将who的输出定向到文件userlist.txt,这是如何做到的呢?

    who的默认输出对象是标准IO中的stdout,文件描述符为1,而重定向所做的事情是将文件描述符1从默认的tty设备文件移开,而重新分配给其他文件,在本例中为userlist.txt,这样who在向文件描述符1输出用户清单时就会输出到userlist.txt中。

    同理,对于输入数据的重定向sort<pricelist.txt来说,被重定向的就是sort的输入源,sort的默认输入源的文件描述符为0,sort从描述符为0的文件——tty输入读取数据,而重定向所做的就是将0从tty输入移开,而分配给pricelist.txt,这样sort就会从pricelist.txt文件中读取数据进行排序,然后输出。

    重定向到文件的小结:

    (1)标准输入、输出、错误分别对应于文件描述符0、1、2;

    (2)内核总是使用最低可用文件描述符;

    (3)文件描述符集合通过exec调用传递,且不会改变。

    shell的重定向功能是通过在fork和exec中间重定向标准输入、输出、错误来实现,如下面例程所示。

    实际上使用管道的who | sort的也是一种重定向,只不过不是重定向到文件,而是重定向到另一个进程,这样就可以实现进程间的交互,这是通过将进程的输入输出重定向到管道来实现的。另外,socket的原理其实和管道很相似。

    /* whotofile.c - fork a child, redirect stdout to file then execute who */
    
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main()
    {
        int fd;
        int pid;
    
        printf( "about to execute who
    " );
        pid = fork();
    
        if( pid == 0 )         //这里是在子进程中做的,也可以不fork子进程直接做,见下一个例程
        {
            close( 1 );             //先关闭文件描述符1,使得最低文件描述符变为1
            creat( "file", 644 );   //在create一个新文件时会使用最低文件描述符
            execlp( "who", "who", NULL );//执行execlp程序时是在同一进程中,因此继承文件描述符
        }
        else
        {
            wait( NULL );
            printf( "who execute finished!
    " );
        }
    
        return 0;
    }

    使用dup2的方法实现重定向:

    /* stdinredir3.c - redirect stdin to file by "open-dup2-close" */
    
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    int main()
    {
        int fd;
        char line[100];
    
        fgets( line, 100, stdin ); printf( "%s", line );
        
        fd = open( "/etc/passwd", O_RDONLY );
        if( fd == -1 )
            perror( "can open" );
        dup2( fd, 0 );
        close( fd );
    
        fgets( line, 100, stdin ); printf( "%s", line );
        fgets( line, 100, stdin ); printf( "%s", line );
        fgets( line, 100, stdin ); printf( "%s", line );
    
        return 0;
    }
  • 相关阅读:
    SQL_Server_2005_启用远程连接
    Oracle外网或内网远程连接
    还原数据库到指定时间点
    SQL Server账号密码(sa)登录失败 错误原因:18456
    sql server如何设置密码过期时间呢?
    安装SQL Server2014 :规则”Windows Management Instrumentation (WMI)服务 “失败
    impala
    dolphinscheduler
    829. Consecutive Numbers Sum 连续的数字求和
    472. Concatenated Words 查找自己拼出来的单词 反向word break
  • 原文地址:https://www.cnblogs.com/uestcliming666/p/13140806.html
Copyright © 2011-2022 走看看