如何解决Linux管道和选择
有一个shell脚本
#!/bin/bash
while :
do
echo "++stdout..";
echo "++stderr.." >> /dev/stderr;
sleep 1
done
和 c 程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
pid_t pid;
int pipefd[2];
int pipe_stderr[2];
char parametr[32];
if(argc != 2)
{
fprintf(stderr,"Niepoprawna liczba argumetnow procesu P \n");
exit(EXIT_FAILURE);
}
/* pipe
pipe0 - write
pipe1 - read
*/
if(pipe(pipefd) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
if(pipe(pipe_stderr) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
sprintf(parametr,"%d",pipefd[0]); //convert - we want to use exec
pid = fork() ;
if(pid < 0)
{
perror("fork!");
}
else if(pid == 0)
{
puts("child");
dup2(pipefd[1],STDOUT_FILENO); // write
dup2(pipe_stderr[1],STDERR_FILENO); // write
close(pipefd[0]);
close(pipe_stderr[0]);
execv(argv[1],&argv[1]);
}
else{
puts("parent");
fd_set set;
struct timeval timeout;
int sel;
char buf;
close(pipefd[1]) ;
close(pipe_stderr[1]) ;
fcntl(pipefd[0],F_SETFL,O_NONBLOCK);
fcntl(pipe_stderr[0],O_NONBLOCK);
FD_ZERO(&set);
FD_SET(pipefd[0],&set); // READ
FD_SET(pipe_stderr[0],&set); // READ
timeout.tv_sec = 17;
timeout.tv_usec = 0;
while(1){
puts("Select");
sel = select(FD_SETSIZE,&set,NULL,&timeout);
if(sel < 0 )
{
perror("Select");
}
else if(sel == 0)
{
printf("No communicate \n");
}
else{
if(FD_ISSET(pipefd[0],&set)){
puts("PARENT_READ_STDOUT:");
while(1){
ssize_t ret = read(pipefd[0],&buf,1);
if(ret > 0){
write(STDOUT_FILENO,1);
}else{
break;
}
}
}
if(FD_ISSET(pipe_stderr[0],&set)){
puts("PARENT_READ_STDERR:");
while(1){
ssize_t ret = read(pipe_stderr[0],1);
if(ret > 0){
write(STDERR_FILENO,1);
}else{
break;
}
}
}
}
}
}
}
输出
./main ./test.sh
是
parent
Select
child
PARENT_READ_STDOUT:
++stdout..
Select
PARENT_READ_STDOUT:
++stdout..
Select
PARENT_READ_STDOUT:
++stdout..
Select
PARENT_READ_STDOUT:
++stdout..
Select
PARENT_READ_STDOUT:
++stdout..
Select
PARENT_READ_STDOUT:
++stdout..
Select
stderr 输出到哪里去了??
解决方法
timeout.tv_sec = 17;
timeout.tv_usec = 0;
while(1){
FD_ZERO(&set);
FD_SET(pipefd[0],&set); // READ
FD_SET(pipe_stderr[0],&set); // READ
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。