认清Linux中标准输入和标准输出的双重含义
按照惯例,UNIX系统shell使用文件描述符0与进程的标准输入(一般是键盘)相关联,文件描述符1与标准输出(一般是显示器)相关联,文件描述符2与标准出错输出(一般是显示器)相关联。
在依从POSIX的应用程序中,幻数0、1、2应当替换成符号常量STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO。这些常量都定义在头文件<unistd.h>中。
一般在教材中不会明确区分,但是我们应注意到标准输入有两层含义:一是指STDIN_FILENO(惯例指定的标准输入设备描述符);另一层含义则是指标准输入设备(如键盘)。同样,标准输出也有两层含义:一是指STDOUT_FILENO(惯例指定的标准输出设备描述符);另一层含义则是指标准输出设备(如显示器)。
scanf函数从标准输入读取内容,我们通常会认为是从键盘读取的。printf函数把内容输出到标准输出,我们通常认为是输出到显示器上。这并没有问题,但前提是“在通常情况下”。
精确地说,scanf函数是从文件描述符STDIN_FILENO(0)所关联的文件中读取,而prinf函数则是输出到文件描述符STDOUT_FILENO(1)所关联的文件中。
如果STDIN_FILENO关联的文件不是键盘,那么scanf就不会从键盘读取内容,同理,如果STDOUT_FILENO关联的文件不是显示器,那么printf也不会将内容输出到显示器。
举例说明(不深究此程序片段意义如何,只为说明上面的叙述而用):
...
int fd[2];
int pid; pipe(fd); if((pid = fork()) < 0)
{
perror("fork");
exit(1);
}
else if(pid == 0) /* 子进程 */
{
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
...
}
else /* 父进程 */
{
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
...
}
子进程中,如果在dup2(fd[1], STDOUT_FILENO); 语句后调用printf函数,那么内容并不会输出到显示器,而是写入了管道中。
父进程中,如果在dup2(fd[0], STDIN_FILENO); 语句后调用scanf函数,那么不会从键盘读取内容,而是从管道中读取。
清楚地了解标准输入和标准输出在特定上下文中的确切含义,有时可以避免不必要的困扰。
最新文章
- 【算法杂谈】Miller-Rabin素性测试算法
- iOS----Xcode6或者Xcode7设置LaunchImage图标
- linux安装软件通常会做哪些事
- codeforces733D. Kostya the Sculptor 偏序cmp排序,数据结构hash,代码简化
- cdr创建样式与样式集的方法
- 【转】C#绝对新手之C#中的多线程小结
- js 拼接 三列做为一行
- JSON数据与JavaScript对象转换
- 获取第下一个兄弟元素 屏蔽浏览器的差异(nextElementsibling)
- Java:Java快速入门
- C#加密与解密
- apache本地多域配置(wampserver本地多域配置)
- Struts2.5 利用Ajax将json数据传值到JSP
- 百度URL 部分参数
- react dnd demo2
- Vue技术内幕 出去看看吧 榨干部分小细节
- laravel passport加密jwt格式的access_token中的sub(user_id)字段
- vuex状态管理
- Spring Cloud Eureka 属性作用
- php插入上万条mysql数据最快的方法
热门文章
- Eclipse配置信息
- 服务器多块磁盘 ,同时磁盘类型混合(SSD+STAT+SAS)
- UVALive 5888 Stack Machine Executor (栈+模拟)
- LC串联谐振回路
- 【破解三网】iphone5 国行 A1429
- TPARAMS和OLEVARIANT相互转换
- SOA和Web Service介绍
- mysql中key 、primary key 、unique key 与index区别
- 在jybot下跑Selenium2Library
- 前端MVC学习总结(三)——AngularJS服务、路由、内置API、jQueryLite