C++ popen 在 fgets 之后立即打开 eof

C++ popen immediate eof after fgets

提问人:Mumbles 提问时间:8/19/2014 最后编辑:CommunityMumbles 更新时间:8/19/2014 访问量:866

问:

我在使用 popen 从 C++ 程序中运行 perl 脚本时遇到问题。

只要我调用 fgets,feof 就会返回 1

到目前为止,我有以下代码。

std::string PerlOutput = "";
std::stringstream CommandToRun;
CommandToRun << "perl " << ScriptFile << " " << ParametersToPass; //Both variables are type std::string
std::cout << "Executing perl script, command to execute is:\n" + CommandToRun.str() << "\n";
FILE * perl_outpipe = popen(CommandToRun.str().c_str(), "r");
unsigned int MaxLineLen = 512;
char buffer[MaxLineLen];
while(!feof(perl_outpipe))
{
    if(fgets(buffer, MaxLineLen, perl_outpipe) != NULL)
    {
        PerlOutput.append(buffer);
    }
}
pclose(perl_outpipe);
std::cout << "Perl script output:\n" << PerlOutput << "\n"; //Huh? It's empty!
std::cout << "length of perl's output: " << PerlOutput.length() << "\n";

这个想法是 perl 的输出可能大于也可能不大于缓冲区,所以对于每次 fgets 调用,我只需将其附加到 std::string 对象中,并在 perl 完成其输出后处理它。

但是没有任何东西被附加到这个字符串中,因为它会立即命中一个 eof。我首先想到,也许我给 popen 的命令可能是错误的。将字符放在错误的位置等,因此在调用 popen 之前,我转储了确切的命令。如果我将此命令复制并粘贴到终端窗口,然后自己运行该命令,它将按预期工作。

Executing perl script, command to execute is:
perl scripts/testscript.pl param1=abc param2=123 param3=Nooo!\ not\ Jackson\ 5!

经过一番阅读,我发现其他人在一年前遇到了完全相同的问题。有一些细微的区别,比如PHP而不是Perl。直接调用脚本,而不是调用解释器,将脚本作为参数。和 CentOS(我使用的是 Debian)。除此之外,它听起来几乎完全一样......

显然,在这种情况下,这是一个权限问题,但我似乎并非如此。

权限包括:

rw-r--r-- mumbles mumbles scripts/testscript.pl
rwxr-xr-x root root /usr/bin/perl

我的程序以我的身份运行(而不是作为它自己的用户),所以它应该有我的权限,对吧?每个人都可以阅读我的脚本,每个人都可以执行 perl。所以,如果我可以以这种方式调用我的脚本,谁能明白为什么我的C++程序不能?

我的程序的输出(在 perl 完成它的事情之后

Perl script output:

length of perl's output: 0
C++ Perl popen fgets feof

评论

0赞 Some programmer dude 8/19/2014
不要这样做,它不会像你期望的那样工作。相反,例如.while (!feof(...))while (fgets(...) != NULL)
0赞 Some programmer dude 8/19/2014
至于你的问题,如果你用相同的参数手动运行脚本,会发生什么?你期望什么输出?哦,不是吗?perl_outpipeNULL
0赞 greggo 8/19/2014
此外,请检查 pclose 的返回值。在命令行上粘贴相同的字符串并不一定证明它在 popen 中运行。
0赞 Mumbles 8/19/2014
我添加了一些 perror 语句来尝试跟踪它的位置......
0赞 Mumbles 8/19/2014
popen 之后,我立即得到了 which 返回.我如上所述更改了 while 循环。并且里面有一个错误 - 它永远不会被调用。我有一个之后得到.好吧,听起来我已经找到了......所以我添加并得到.所以显然没有错误。最后,我添加了哪些打印 我能看到的唯一错误是到达文件末尾。perror("popen");popen Successperror("fgets-after");fgets-after: Invalid argumentstd::cout << "ferror " << ferror(perl_outpipe)ferror 0std::cout << "feof " << feof(perl_outpipe)feof 1

答: 暂无答案