
正文
linux管道命令错误 linux中管道
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
Linux下管道通信出错
问题在这个while上
不是
while( (n = read(fd, buff, MAXLINE) 0 ) )//读取文件里的内容
应该是(注意括号括的地方)
while( (n = read(fd, buff, MAXLINE) ) 0 )//读取文件里的内容
{
/*这个地方出错了,源程序中不包含注释这部分代码
//cout n endl; //这里为什么n都是
//n = strlen(buff); //这里都是MAXLINE
//cout n endl;
//buff[n] = '\0';
*/
相关问答
Q1: 求linux大神指点我的管道程序有什么错误?
这里有两点要注意,第一,如果没有读打开管道,那么写打开管道就阻塞,而且不能非阻塞地打开;第二,如果没有写打开管道,那么读打开管道也阻塞,但是可以在open中指定O_NONBLOCK来非阻塞打开。一般读写分别在两个进程中。但在一个进程中也可以分别打开读写,但要先以非阻塞方式打开读。你的代码阻塞在了读打开管道.
根据你的代码,我重新写了一个实现。先将用户输入保存再DATAFILE中,再经过FIFO将数据读取并写入SAVEFILE中
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include errno.h
#define FIFO "/tmp/fifo"
#define DATAFILE "./data_file"
#define SAVEFILE "./save_file"
static int input_data(const char *filename);
static int process_fifo(const char *filename);
int main(int argc, char *argv[])
{
input_data(DATAFILE);
process_fifo(DATAFILE);
return 0;
}
#define BUFSIZE 1024
static int input_data(const char *filename)
{
printf("input data:\n");
char buf[BUFSIZE];
int n=read(STDIN_FILENO,buf,BUFSIZE);
if(n0){
perror("read from stdin error");
exit(EXIT_FAILURE);
}
int fd=open(filename,O_CREAT|O_TRUNC|O_RDWR,0666);
if(fd0){
perror("create data file error");
exit(EXIT_FAILURE);
}
if(n!=write(fd,buf,n)){
perror("write to data file error");
exit(EXIT_FAILURE);
}
close(fd);
return 0;
}
static int process_fifo(const char *filename)
{
int rfd=open(filename,O_RDONLY);
if(rfd0){
perror("read from data file error");
exit(EXIT_FAILURE);
}
unlink(FIFO);
if(mkfifo(FIFO,0666)!=0){
perror("failed to create FIFO");
exit(EXIT_FAILURE);
}
int fifo_r,fifo_w;
fifo_r=open(FIFO,O_RDONLY|O_NONBLOCK);
fifo_w=open(FIFO,O_WRONLY);
if(fifo_r0||fifo_w0){
perror("open FIFO error");
exit(EXIT_FAILURE);
}
int n;
char buf[BUFSIZE];
/* 从数据文件中读取数据 */
n=read(rfd,buf,BUFSIZE);
if(n0){
perror("read from data file error");
exit(EXIT_FAILURE);
}
/* 写入管道 */
if(n!=write(fifo_w,buf,n)){
perror("write to FIFO error");
exit(EXIT_FAILURE);
}
/* 从管道读取 */
memset(buf,0,BUFSIZE);
n=read(fifo_r,buf,BUFSIZE);
if(n0){
perror("read from FIFO error");
exit(EXIT_FAILURE);
}
/* 打开保存数据的文件 */
int wfd=open(SAVEFILE,O_CREAT|O_TRUNC|O_WRONLY,0666);
if(wfd0){
perror("create save file error");
exit(EXIT_FAILURE);
}
if(n!=write(wfd,buf,n)){
perror("write to FIFO error");
exit(EXIT_FAILURE);
}
/* 结束 */
close(rfd);
close(wfd);
close(fifo_r);
close(fifo_w);
return 0;
}
Q2: Linux管道命令(pipe)
管道命令就是用来连接多条指令的,前一条指令的输出流向会作为后一条指令的操作对象。
管道命令的操作符是:|,它只能处理由前面一条指令传出的正确输出信息,对错误信息是没有直接处理能力的。然后,传递给下一条指令,作为操作对象。
基本格式:
指令1 | 指令2 | …
【指令1】正确输出,作为【指令2】的输入,然后【指令2】的输出作为【指令3】的输入,如果【指令3】有输出,那么输出就会直接显示在屏幕上面了。通过管道之后【指令1】和【指令2】的正确输出是不显示在屏幕上面的。
【提醒注意】
管道命令只能处理前一条指令的正确输出,不能处理错误输出;
管道命令的后一条指令,必须能够接收标准输入流命令才能执行。
使用示例
1、分页显示/etc目录中内容的详细信息
$ ls -l /etc | more
2、将一个字符串输入到一个文件中
$ echo “hello world” | cat hello.txt
Q3: linux关于管道说法错误的是什么
Linux关于管道 原创
2018-09-14 12:22:41
Gaodes
码龄5年
关注
管道的概念
管道是Unix中最古老的进程间通信的形式。 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道” 我们通常把是把一个进程的输出连接或“管接”(经过管道来连接)到另一个进程的输入。
管道特点
管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)进行通信;通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道。
pipe函数
包含头文件unistd.h 功能:创建一无名管道 原型
int pipe(int file_descriptor[2]);
参数 file_descriptor:文件描述符数组,其中file_descriptor[0]表示读端,file_descriptor[1]表示写端 返回值:成功返回0,失败返回错误代码
示例代码:
#includestdio.h
#includeunistd.h
#includestdlib.h
#includesignal.h
#includestring.h
int main(int argc,char *argv[])
{
int fd[2];
printf("f[0]=%d,f[1]=%d\n",fd[0],fd[1]);
pipe(fd);
printf("f[0]=%d,f[1]=%d\n",fd[0],fd[1]);
char buf[1024]={0};
int fid = fork();
if(fid 0)
{
read(fd[0],buf,1024);
printf("read data %s\n",buf);
}
else if(fid == 0)
{
write(fd[1],"helloworld",strlen("helloworld"));
}
else
{
perror("fork error");
}
return 0;
}
打印结果
管道读写规则:如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生 当没有数据可读时,read调用就会阻塞,即进程暂停执行,一直等到有数据来到为止。 如果管道的另一端已经被关闭,也就是没有进程打开这个管道并向它写数据时,read调用就会阻塞
复制文件描述符dup
#includestdio.h
#includestdlib.h
#includestring.h
#includesignal.h
int main()
{
int fd = dup(1);
printf("file fd= %d\n",fd);
write(fd,"helloworld",strlen("helloworld"));
return 0;
}
打印结果:
1为输入到终端
shell管道的实现
原理通过把发的fd[1]写复制到shell的1(标准输入),fd[0]复制到shell的2(标准输出)
以下是代码:
#includestdio.h
#includestdlib.h
#includefcntl.h
#includeunistd.h
#includestring.h
#includesignal.h
int main()
{
int fd[2];
char buf[1024] ={0};
pipe(fd);
int pid = fork();
if(pid 0)
{
read(fd[0],buf,1024);
printf(buf);
}
else if(pid == 0)
{
dup2(fd[1],1);
close(fd[0]);
close(fd[1]);
execlp("ls","ls","-al",NULL);
}
else
{
}
return 0;
}
实现结果:
popen函数
作用:允许一个程序把另外一个程序当作一个新的进程来启 动,并能对它发送数据或接收数据
FILE* popen(const char *command, const char *open_mode);
command:待运行程序的名字和相应的参数 open_mode:必须是“r”或“w” 如果操作失败,popen会返回一个空指针
以下代码:
#includestdio.h
#includestdlib.h
#includesys/types.h
#includesys/stat.h
#includefcntl.h
#includestring.h
int main()
{
FILE *file = popen("ls -al","r");
char buf[1024] = {0};
fread(buf,1,1024,file);
fclose(file);
FILE *wcfile = popen("wc","w");
fwrite(buf,1,strlen(buf),wcfile);
fclose(wcfile);
return 0;
}
代码结果:
命名管道破裂测试
我们首先要知道命名管道,要读段和写段同时开启,才能向文件读写数据。
贴上代码来理解命名管道的规则
首先是读端:
#includestdio.h
#includeunistd.h
#includestdlib.h
#includesignal.h
#includestring.h
#includefcntl.h
int main(int argc,char *argv[])
{
printf("open before\n");
int fd = open("/home/gao/tmp/fifo",O_RDONLY);
printf("open after\n");
//休眠5秒,读端退出
sleep(5);
return 0;
}
接下来是写端:
#includestdio.h
#includeunistd.h
#includestdlib.h
#includesignal.h
#includestring.h
#includefcntl.h
void handle(int signo)
{
printf("cat signale = %d\n",signo);
}
int main(int argc,char *argv[])
{
signal(SIGPIPE,handle);
printf("open before\n");
int fd = open("/home/gao/tmp/fifo",O_WRONLY);
printf("open after\n");
//命名管道规则,如果写入读断被中断,写入会返回-1,并且管道会破裂,产生信号(SIGPIPE)
while(1)
{
int wrsize = write(fd,"helloworld",strlen("helloworld"));
printf("size data:%d\n",wrsize);
sleep(1);
}
}
执行写端:
它在等待另一端的开启,才能向里面写入数据
此时我们开启读端:
马上可以看到写段可以写数据
而执行5秒后,我们可以看到写的时候返回-1,并且获取到管道破裂的信息(SIGPIPE)
所以这里就是我们所注意的点,当我们写客户端和服务器进行管道传输的时候,如果客户端一旦退出来,就会使管道破裂,所以我们必须通过捕捉信号,来避免这种事情发生。
关于linux管道命令错误和linux中管道的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。







