【问题标题】:C++ apt-get working on stdout of popenC++ apt-get 处理 popen 的标准输出
【发布时间】:2011-08-12 12:29:14
【问题描述】:

这听起来像是一个愚蠢的问题,我是 C++ 新手。

在 debian 上,我尝试使用 popen 调用 apt-get install。我需要解析这个程序的输出。不幸的是,我无法阅读 apt-get 的完整输出。

在某些时候 apt-get 可能会要求用户输入(询问是否应该安装依赖项)。我的程序无法输出这一行。

什么是最后一行(参见下面的示例,我的程序中缺少的行是:“您要继续 [Y/n] 吗?”)没有输出?

当我手动运行 apt-get 命令时,控制台输出如下所示:

$ sudo apt-get install python-wxtools
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  python-wxgtk2.8 python-wxversion
Suggested packages:
  wx2.8-doc wx2.8-examples ruby wish tk8.5 tcsh csh octave3.0 mksh pdksh
  python-xml editra
The following NEW packages will be installed:
  python-wxgtk2.8 python-wxtools python-wxversion
0 upgraded, 3 newly installed, 0 to remove and 8 not upgraded.
Need to get 5,942kB of archives.
After this operation, 25.0MB of additional disk space will be used.
Do you want to continue [Y/n]? 

注意:最后一行末尾没有换行符。

当我使用自己的程序时,最后一行丢失(输出)

$ sudo ./test/popen 
g++ -Wall -o test/popen test/popen.cpp
test/popen.cpp: In function ‘int main(int, char**, char**)’:
test/popen.cpp:22: warning: comparison between signed and unsigned integer expressions
apt-get install python-wxtools
Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
  python-wxgtk2.8 python-wxversion
Suggested packages:
  wx2.8-doc wx2.8-examples ruby wish tk8.5 tcsh csh octave3.0 mksh pdksh
  python-xml editra
The following NEW packages will be installed:
  python-wxgtk2.8 python-wxtools python-wxversion
0 upgraded, 3 newly installed, 0 to remove and 8 not upgraded.
Need to get 5,942kB of archives.
After this operation, 25.0MB of additional disk space will be used.

注意:输出末尾的换行符

我在 c++ 中的 popen 参考实现如下所示:

// $Id: popen.cpp 126 2011-04-25 18:48:02Z wus $

#include <iostream>
#include <stdio.h>

using namespace std;

/**
 * run debians apt-get and check output
 */
int main(int argc, char **argv, char **envp) { 

    FILE *fp;
    char buffer[9];
    // must use a package which asks for dependencies
    char command[255] = "apt-get install python-wxtools";
    cout << command << endl;

    // Execute command, open /dev/stdout for reading
    fp = popen(command, "r");

    // read output character by character
    while (fread(buffer, 1, 1, fp) != EOF) {
        cout << buffer;
    }

    // close
    pclose(fp);
}

我尝试在 Linux 系统上这样做

$ uname -a
Linux shell1 2.6.35-28-server #50-Ubuntu SMP Fri Mar 18 18:59:25 UTC 2011 x86_64 GNU/Linux

$ gcc --version
gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【问题讨论】:

    标签: c++ debian popen apt-get debian-based


    【解决方案1】:

    尝试将-y 选项添加到apt-get。这将使它假设用户对所有事情都说“是”,这应该使它“正常工作”。我认为它现在失败了,因为它想提示用户,但它意识到没有可用的键盘输入(可能通过调用isatty(3))所以它放弃了。

    【讨论】:

    • 我希望我的程序的用户选择是否要获取额外的依赖项,因此 apt-get install -y 不幸的是,我没有选择(-y 将回答所有问题«是“ 自动地)。谢谢你的回答。
    • 所以你想捕获 apt-get 的输出,并且还给它输入。那是不可能的。由于某些原因,请参见此处:lua-users.org/lists/lua-l/2007-10/msg00189.html
    • 您可能会考虑使用-s 进行“试运行”,向用户显示其输出,提示他们,然后如果他们同意,则使用-y 再次运行...。您可能还可以考虑为此使用 C++ 以外的语言。
    • Zwick:我可以将 Y 或 N 发送回 apt-get。返回作品,这不是我的问题。但我看不懂最后一行似乎是 readline 所写的。试运行听起来像是一种解决方法,谢谢。但我也想找到一种方法来阅读最后一行。
    • 我担心的是 apt-get 没有发出最后一行,因为它识别出没有用户。如果您在 strace 下运行 apt-get ,也许您可​​以查看它是否打印该行,或者它是否调用 isatty(可能带有参数 0)。如果它确实使用 isatty 来决定是否打印提示,那么让所有这些工作的一种方法是让您在程序中创建的伪终端中运行它。然而,这是一门相当黑暗的艺术,并且可能本身就是一个重大项目。
    【解决方案2】:

    问题实际上不是输入缓冲,而是 cout 的输出缓冲。手动冲洗解决了这个问题:

    while (fread(buffer, 1, 1, fp) != EOF) {
        cout << buffer << flush;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      相关资源
      最近更新 更多