zoukankan      html  css  js  c++  java
  • (文件描述符0、1、2),(stdin、stdout、stderr),(终端设备)这三者之间的关系???

    前言

    在Linux系统中,一切设备都看作文件。而每打开一个文件,就有一个代表该打开文件的文件描述符。程序启动时默认打开三个I/O设备文件:标准输入文件stdin,标准输出文件stdout,标准错误输出文件stderr,分别得到文件描述符 0, 1, 2。

    实例

    现在来看一个 测试ttyname函数的实例(ttyname函数功能是返回在该文件描述符上打开的终端设备的路径名)

    #include "apue.h"

    int

    main(void)

    {

        char *name;

        if(isatty(0))

        {

            name = ttyname(0);

            if(name == NULL)

                name = "undefined";

        }

        else

        {

            name = "not a tty";

        }

        printf("fd 0: %s ", name);

        if(isatty(1))

        {

            name = ttyname(1);

            if(name == NULL)

                name = "undefined";

        }

        else

        {

            name = "not a tty";

        }

        printf("fd 1: %s ", name);

        if(isatty(2))

        {

            name = ttyname(2);

            if(name == NULL)

                name = "undefined";

        }

        else

        {

            name = "not a tty";

        }

        printf("fd 2: %s ", name);

        

        exit(0);

    }

    运行该程序得到:

    从程序运行结果来看,在文件描述符0、1和2上打开的终端设备都是/dev/tty1. 那么疑问就来了,前言中明确指出文件描述符0、1和2是打开标准输入文件stdin,标准输出文件stdout和标准错误输出文件stderr分别得到的。那么文件描述符0、1和2到底是打开哪个文件得到的呢?这里该如何解释呢???望懂得其中缘由者指点一二,小弟万分感谢!

    自我解答

    如果从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2), 0与进程的标准输入相关联,1与进程的标准输出相关联,2与进程的标准错误输出相关联。文件描述符0、1、2默认打开为标准输入、标准输出和标准出错,这是肯定的。打开一终端设备(如/dev/tty),自然也得到一个文件描述符(ttyfiledes),然后把为终端设备打开的文件描述符复制到标准输入、标准输出和标准出错,比如使用如下语句实现复制:

    dup2(ttyfiledes, 0);

    dup2(ttyfiledes, 1);

    dup2(ttyfiledes, 2);

    这样的话,文件描述符0、1、2就关联到了/dev/tty. 

     此后再执行输入和输出的话,对象都是终端设备/dev/tty了。也就是说,输入是从终端设备/dev/tty读取数据,而输出则是将数据写到终端设备/dev/tty.

    上面的解答只是个人的猜想,不知是否正确,不过至少这是一个让自己感觉还算合理的解释。如解释不恰当,还望高手赐教!

     继续自解:

    每一个进程都有自己的标准输入文件、标准输出文件和标准出错文件(应该是系统自动分配的)。而且系统默认自动为进程的标准输入文件在文件描述符0上打开,标准输出文件在文件描述符1上打开,标准出错在文件描述符2上打开。通常情况下,是将输入设备(键盘)打开并复制到进程的标准输入(0)、将输出设备(显示器)打开并复制到标准输出(1)和标准出错(2)。

  • 相关阅读:
    可视化开发_AppInventor2似乎被抛弃了
    PHP内核学习(一)SAPI
    代码整洁之道(一)理论篇
    Silence.js高效开发移动Web前端类库
    梦游前端,JavaScript兼容性
    20分钟入门正则表达式
    原生Javascript 省市区下拉列表插件
    Tortoise-SVN 出现“unable to connect to a repository at url no element found”解决办法
    PHP实现好友生日邮件提醒
    第一份工作
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3577223.html
Copyright © 2011-2022 走看看