2013-02-10 3 views
1

Я пытаюсь использовать vala для запуска внешнего приложения с помощью GLib с помощью spawn_command_line_sync(). В соответствии с документацией (http://valadoc.org/#!api=glib-2.0/GLib.Process.spawn_sync) вы можете передать строку для хранения вывода внешнего приложения.Перенаправление вывода внешнего приложения начинается с glib

Хотя это отлично работает при запуске скрипта, который печатает пару строк, мне нужно вызвать программу, которая будет печатать содержимое двоичного файла. (например, «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); 
} 

ответ

2

GLib.Process.spawn_async_with_pipes позволит вам сделать это. Он запускает процессы и возвращает файловый дескриптор для каждого из stdout, stderr и stdin. В ValaDoc есть образец кода о том, как настроить IOChannel s для контроля вывода.

1

Спасибо за это, я должен перепробовать spawn_async_with_pipes(), возвращающий ints, а не строки.

Есть ли что-то не так с этим? (кроме размера буфера 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); 
    } 
} 
+1

Ничего плохие, но вы должны вызвать 'waitpid' или добавить' ChildWatch' к вашему основному циклу, таким образом Вы можете получить статус СУЩЕСТВУЕТ ваш ребенок. Если нет, он становится зомбиком до тех пор, пока вы не выйдете, и он будет перезапущен «init» и получен. – apmasell

+0

Возможно, вам захочется использовать GLib.OutputStream.splice (в gio-2.0). – nemequ