您的位置:首页 > 运维架构 > Linux

Unix-Linux编程实践教程——第十章

2017-10-22 13:17 357 查看

章节概要

本章节介绍IO重定向以及管道

listargs.c

/*************************************************************
> File Name: listargs.c
> Author: Duke-wei
> Mail: 13540639584@163.com
> Created Time: 2017年10月15日 星期日 10时05分19秒
*************************************************************/
//试水一波:./a.out testing>xyz one two 2>oops
//结果是xyz存放stdout的输出,oops存放stderr输出,为啥?
//1.shell不把重定向标记和文件名传递给程序
//2.重定向可以出现在命令行中任意地方,并且重定向标识符周围不需要空格来区分
//试水一波:./a.out testing>xyz one two>oops
//结果是只有oops存放stdout的输出
#include<stdio.h>
int main(int ac,char* av[]){
int i;
printf("Number of args:%d,Args are:\n",ac);
for(i=0;i<ac;++i){
printf("args[%d] %s\n",i,av[i]);
}
fprintf(stderr,"This message is sent to stderr.\n");
return 0;
}


stdinredir1.c

/**********************************************************
> File Name: stdinredir1.c
> Author: Duke-wei
> Mail: 13540639584@163.com
> Created Time: 2017年10月15日 星期日 10时37分40秒
**********************************************************/
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>

int main(){
int fd;
char line[100];
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
//这里关闭了文件句柄0,则下次打开文件的时候默认分配最小句柄即0指向了passwd文件
close(0);
fd = open("/etc/passwd",O_RDONLY);
if(fd!=0){
fprintf(stderr,"Could not open data as fd 0\n");
exit(1);
}
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
close(fd);
return 0;
}


stdinredir2.c

/*********************************************************
> File Name: stdinredir2.c
> Author: Duke-wei
> Mail: 13540639584@163.com
> Created Time: 2017年10月15日 星期日 10时47分35秒
*********************************************************/
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#define CLOSE_DUP
#define USE_DUP2
int main(){
int fd;
int newfd;
char line[100];
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
fd = open("data",O_RDONLY);
#ifdef CLOSE_DUP
close(0);
//dup实现fd的复制
newfd = dup(fd);
#else
//dup2实现了上面两部操作
newfd = dup2(fd,0);
#endif
if(newfd!=0){
fprintf(stderr,"Could not duplicate fd to 0\n");
exit(1);
}
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;
}


whotofile.c

/********************************************************
> File Name: whotofile.c
> Author: Duke-wei
> Mail: 13540639584@163.com
> Created Time: 2017年10月15日 星期日 11时51分02秒
*******************************************************/
//标准输入、输出以及错误输出分别对应文件描述符0,1,2
//内核总是使用最低可用文件描述符
//文件描述符集合通过exec调用传递,且不会被改变
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
int main(){
int pid;
int fd;
printf("About to run who into a file\n");
if((pid=fork())==-1){
perror("fork");
exit(1);
}
if(pid==0){
//这里关闭1对父进程没有影响
close(1);
//因为关闭了1,所以fd会分配到1
fd = creat("userlist",0644);
//execlp执行完输出到1,而此刻1是userlist的文件句柄,因此输出会输出到userlist里
execlp("who","who",NULL);
perror("execlp");
exit(1);
}
if(pid!=0){
wait(NULL);
printf("Done running who.results in userlist\n");
}
return 0;
}


pipedemo.c

/***********************************************************
> File Name: pipedemo.c
> Author: Duke-wei
> Mail: 13540639584@163.com
> Created Time: 2017年10月15日 星期日 12时12分06秒
***********************************************************/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>

int main(){
int len,i,apipe[2];
char buf[BUFSIZ];
//构建管道
if(pipe(apipe)==-1){
perror("could not make pipe");
exit(1);
}
printf("Got a pipe! It is file descriptors:{%d %d}\n",apipe[0],apipe[1]);
while(fgets(buf,BUFSIZ,stdin)){
len = strlen(buf);
//apipe[1]写入端
if(write(apipe[1],buf,len)!=len){
perror("writing to pipe");
break;
}
for(i=0;i<len;++i){
buf[i]='X';
}
//apipe[0]读取端
len = read(apipe[0],buf,BUFSIZ);
if(len==-1){
perror("reading from pipe");
break;
}
if(write(1,buf,len)!=len){
perror("writing to stdout");
break;
}
}
return 0;
}


pipedemo2.c

/***********************************************************
> File Name: pipedemo2.c
> Author: Duke-wei
> Mail: 13540639584@163.com
> Created Time: 2017年10月15日 星期日 12时12分06秒
**********************************************************/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>

#define CHILD_MESS "I want a cookie\n"
#define PAR_MESS "testing..\n"
#define oops(m,x) { perror(m); exit(x); }

int main(){
int pipefd[2];
int len;
char buf[BUFSIZ];
int read_len;
if(pipe(pipefd)==-1){
oops("cannot get a pipe",1);
}
switch(fork()){
case -1:
oops("cannot fork",2);
case 0:
len = strlen(CHILD_MESS);
while(1){
if(write(pipefd[1],CHILD_MESS,len)!=len) oops("write",3);
sleep(5);
}
default:
len = strlen(PAR_MESS);
while(1){
if(write(pipefd[1],PAR_MESS,len)!=len) oops("write",4);
sleep(1);
read_len = read(pipefd[0],buf,BUFSIZ);
if(read_len<=0) break;
write(1,buf,read_len);
}
}
return 0;
}


pipe.c

/***********************************************************
> File Name: pipe.c
> Author: Duke-wei
> Mail: 13540639584@163.com
> Created Time: 2017年10月15日 星期日 12时12分06秒
************************************************************/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>

#define oops(m,x) { perror(m); exit(x); }

int main(int ac,char** av){
int pipefd[2];
int pid;
if(ac!=3){
fprintf(stderr,"usage:pipe cmd1 cmd2\n");
exit(1);
}
if(pipe(pipefd)==-1){
oops("cannot get a pipe",1);
}
if((pid=fork())==-1){
oops("Cannot fork",2);
}
if(pid>0){
//子进程关闭pipefd[1]
close(pipefd[1]);
//将0连接到pipefd[0]后关闭pipefd[0]
if(dup2(pipefd[0],0)==-1) oops("could not redirect stdin",3);
close(pipefd[0]);
execlp(av[2],av[2],NULL);
oops(av[2],4);
}else{
close(pipefd[0]);
//将管道写入的一端连接到stdout
if(dup2(pipefd[1],1)==-1) oops("could not redirect stdout",4);
close(pipefd[1]);
execlp(av[1],av[1],NULL);
oops(av[1],5);
}
return 0;
}


linux 管道读写规则

管道的具体读取规则参考linux 管道读写规则
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: