【问题标题】:Redirecting output of an external application started with glib重定向使用 glib 启动的外部应用程序的输出
【发布时间】:2013-02-10 17:18:46
【问题描述】:

我正在尝试使用 vala 使用带有 spawn_command_line_sync() 的 GLib 启动外部应用程序。 根据文档 (http://valadoc.org/#!api=glib-2.0/GLib.Process.spawn_sync),您可以传递一个字符串来存储外部应用程序的输出。

虽然这在启动打印几行的脚本时可以正常工作,但我需要调用一个程序来打印二进制文件的内容。 (例如“cat /usr/bin/apt-get”)

有什么方法可以接收外部程序的输出,而不是字符串,而是 DataStream 或类似的输出?

我打算将外部程序的输出写入文件,因此只需调用“cat /usr/bin/apt-get > outputfile”将是一种替代方法(不是很好),但它不是似乎有效。

无论如何,我希望它获得某种输出流。 我将不胜感激。

我正在使用的代码:

using GLib;

static void main(string[] args) {
    string execute = "cat /usr/bin/apt-get";
    string output = "out";

    try {
        GLib.Process.spawn_command_line_sync(execute, out output);
    } catch (SpawnError e) {
        stderr.printf("spawn error!");
        stderr.printf(e.message);
    }

    stdout.printf("Output: %s\n", output);
}

【问题讨论】:

    标签: glib output vala


    【解决方案1】:

    GLib.Process.spawn_async_with_pipes 会让你做到这一点。它生成进程并为stdoutstderrstdin 中的每一个返回一个文件描述符。 ValaDoc 中有一个代码示例,说明如何设置IOChannels 来监控输出。

    【讨论】:

      【解决方案2】:

      谢谢你,我必须重读 spawn_async_with_pipes() 返回整数而不是字符串。

      这样做有什么问题吗? (除了缓冲区大小为 1)

      using GLib;
      
      static void main(string[] args) {
      
          string[] argv = {"cat", "/usr/bin/apt-get"};
          string[] envv = Environ.get();
          int child_pid;
          int child_stdin_fd;
          int child_stdout_fd;
          int child_stderr_fd;
      
          try {
              Process.spawn_async_with_pipes(
                  ".",
                  argv,
                  envv,
                  SpawnFlags.SEARCH_PATH,
                  null,
                  out child_pid,
                  out child_stdin_fd,
                  out child_stdout_fd,
                  out child_stderr_fd);
      
          } catch (SpawnError e) {
              stderr.printf("spawn error!");
              stderr.printf(e.message);
              return;
          }
      
          FileStream filestream1 = FileStream.fdopen(child_stdout_fd, "r");
          FileStream filestream2 = FileStream.open("./stdout", "w");
      
          uint8 buf[1];
          size_t t;
          while ((t = filestream1.read(buf, 1)) != 0) {
              filestream2.write(buf, 1);
          }
      }
      

      【讨论】:

      • 没有错,但是您应该调用waitpid 或在主循环中添加ChildWatch,以便收集孩子的存在状态。如果没有,它会变成僵尸,直到你退出并由 init 重新设置父项并收割。
      • 您可能需要考虑使用 GLib.OutputStream.splice(在 gio-2.0 中)。
      猜你喜欢
      • 2014-07-01
      • 2013-12-25
      • 2011-08-03
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      相关资源
      最近更新 更多