popen 获取不完整且延迟了

时间:2022-11-10 18:04:12
我用最普遍的方法popen一个FILE,然后在while里面fgets或者fread都试过,但是不能获取另外一个进程所有的输出(读出来的内容与其直接在shell里启动的少了很多内容)
有的内容则是等到输出了N行之后,才获取到输出

是因为缓冲?还是它输出到的地方不是shell?我需要实时能获取每一句啊 popen 获取不完整且延迟了

另外一个进程是CSGO的运行服务端,我想要根据它输出提示需要更新的语句后,自动运行更新工具

16 个解决方案

#1


应该是因为popen的进程使用了fully buffered。如果你能修改它的程序,可以加上flush。如果不能修改,需要利用pseudo terminal使其变成line buffered。具体方法见APUE 19章第5节。

#2


至于会少输出,可能是因为有stderr的内容。

#3


引用 2 楼 colddown 的回复:
至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了

#4


引用 3 楼 rsdtt 的回复:
Quote: 引用 2 楼 colddown 的回复:

至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了
那就比较奇怪了,用APUE的方法试下吧,看看结果。

#5


引用 4 楼 colddown 的回复:
Quote: 引用 3 楼 rsdtt 的回复:

Quote: 引用 2 楼 colddown 的回复:

至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了
那就比较奇怪了,用APUE的方法试下吧,看看结果。


还有就是什么情况下会出现shell要达到一定的量,才获取得到输出。。。

#6


引用 5 楼 rsdtt 的回复:
Quote: 引用 4 楼 colddown 的回复:

Quote: 引用 3 楼 rsdtt 的回复:

Quote: 引用 2 楼 colddown 的回复:

至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了
那就比较奇怪了,用APUE的方法试下吧,看看结果。


还有就是什么情况下会出现shell要达到一定的量,才获取得到输出。。。


terminal is line buffered 

#7


引用 6 楼 micropentium6 的回复:
Quote: 引用 5 楼 rsdtt 的回复:

Quote: 引用 4 楼 colddown 的回复:

Quote: 引用 3 楼 rsdtt 的回复:

Quote: 引用 2 楼 colddown 的回复:

至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了
那就比较奇怪了,用APUE的方法试下吧,看看结果。


还有就是什么情况下会出现shell要达到一定的量,才获取得到输出。。。


terminal is line buffered 


能否详细一些,完全看不懂。。。总之一般启动,shell就会一行一行的列出信息,然后用popen+fgets或者fread,都要一大段才读出来,而且读取的信息不完整

#8


不是不完整,准确的说是有些信息读不出来

#9


该回复于2014-07-25 09:05:57被管理员删除

#10


贴下输出,还有读取程序可能有帮助

#11


贴下输出,还有读取程序可能有帮助

#12


贴下输出,还有读取程序可能有帮助

#13


这不科学啊!
除非有些信息输出到了标准错误。

#14


引用 12 楼 colddown 的回复:
贴下输出,还有读取程序可能有帮助


	FILE *ptr;
if((ptr=popen(runcmd, "r"))!=NULL)
{
while(fgets(buf, 2048, ptr)!=NULL)
{
if (CheckPopenUpdate(buf) == true)
{
g_needupdate = 1;
break;
}
}
pclose(ptr);
NBLog("ThreadRunSrcds thread end");
KillSrcds(*port);
}

#15


引用 13 楼 mymtom 的回复:
这不科学啊!
除非有些信息输出到了标准错误。


我也觉得特不科学,而且还有哦,就是有的输出内容我居然不进入我的fgets里面。。

#16


FILE *ptr;
char tmpbuf[256];
if((ptr=popen(runcmd, "r"))!=NULL)
{
setvbuf(ptr, tmpbuf, _IOFBF, sizeof(tmpbuf));
while(fgets(buf, 2048, ptr)!=NULL)
{
printf("buf:%s\n", buf);
if (CheckPopenUpdate(buf) == true)
{
g_needupdate = 1;
break;
}
}
pclose(ptr);
NBLog("ThreadRunSrcds thread end");
KillSrcds(*port);
}


输出部分代码应该是这样的,上面那段我把输出写进CheckPopenUpdate里了

#1


应该是因为popen的进程使用了fully buffered。如果你能修改它的程序,可以加上flush。如果不能修改,需要利用pseudo terminal使其变成line buffered。具体方法见APUE 19章第5节。

#2


至于会少输出,可能是因为有stderr的内容。

#3


引用 2 楼 colddown 的回复:
至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了

#4


引用 3 楼 rsdtt 的回复:
Quote: 引用 2 楼 colddown 的回复:

至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了
那就比较奇怪了,用APUE的方法试下吧,看看结果。

#5


引用 4 楼 colddown 的回复:
Quote: 引用 3 楼 rsdtt 的回复:

Quote: 引用 2 楼 colddown 的回复:

至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了
那就比较奇怪了,用APUE的方法试下吧,看看结果。


还有就是什么情况下会出现shell要达到一定的量,才获取得到输出。。。

#6


引用 5 楼 rsdtt 的回复:
Quote: 引用 4 楼 colddown 的回复:

Quote: 引用 3 楼 rsdtt 的回复:

Quote: 引用 2 楼 colddown 的回复:

至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了
那就比较奇怪了,用APUE的方法试下吧,看看结果。


还有就是什么情况下会出现shell要达到一定的量,才获取得到输出。。。


terminal is line buffered 

#7


引用 6 楼 micropentium6 的回复:
Quote: 引用 5 楼 rsdtt 的回复:

Quote: 引用 4 楼 colddown 的回复:

Quote: 引用 3 楼 rsdtt 的回复:

Quote: 引用 2 楼 colddown 的回复:

至于会少输出,可能是因为有stderr的内容。


那我尝试一下用pipe读stderr,看它正常输出的内容不可能是err的说 popen 获取不完整且延迟了
那就比较奇怪了,用APUE的方法试下吧,看看结果。


还有就是什么情况下会出现shell要达到一定的量,才获取得到输出。。。


terminal is line buffered 


能否详细一些,完全看不懂。。。总之一般启动,shell就会一行一行的列出信息,然后用popen+fgets或者fread,都要一大段才读出来,而且读取的信息不完整

#8


不是不完整,准确的说是有些信息读不出来

#9


该回复于2014-07-25 09:05:57被管理员删除

#10


贴下输出,还有读取程序可能有帮助

#11


贴下输出,还有读取程序可能有帮助

#12


贴下输出,还有读取程序可能有帮助

#13


这不科学啊!
除非有些信息输出到了标准错误。

#14


引用 12 楼 colddown 的回复:
贴下输出,还有读取程序可能有帮助


	FILE *ptr;
if((ptr=popen(runcmd, "r"))!=NULL)
{
while(fgets(buf, 2048, ptr)!=NULL)
{
if (CheckPopenUpdate(buf) == true)
{
g_needupdate = 1;
break;
}
}
pclose(ptr);
NBLog("ThreadRunSrcds thread end");
KillSrcds(*port);
}

#15


引用 13 楼 mymtom 的回复:
这不科学啊!
除非有些信息输出到了标准错误。


我也觉得特不科学,而且还有哦,就是有的输出内容我居然不进入我的fgets里面。。

#16


FILE *ptr;
char tmpbuf[256];
if((ptr=popen(runcmd, "r"))!=NULL)
{
setvbuf(ptr, tmpbuf, _IOFBF, sizeof(tmpbuf));
while(fgets(buf, 2048, ptr)!=NULL)
{
printf("buf:%s\n", buf);
if (CheckPopenUpdate(buf) == true)
{
g_needupdate = 1;
break;
}
}
pclose(ptr);
NBLog("ThreadRunSrcds thread end");
KillSrcds(*port);
}


输出部分代码应该是这样的,上面那段我把输出写进CheckPopenUpdate里了