Unix / C ++: открыть новый терминал и перенаправить вывод на него - PullRequest
4 голосов
/ 03 апреля 2012

Моя программа (C ++ на Solaris 10) записывает вывод через wcout на свой терминал при запуске из оболочки. Но когда я запускаю его изнутри Sun Studio или файловый менеджер не имеет терминала, и выходной результат появляется в окне вывода Sun Studio или вообще не появляется.

Я хотел бы, чтобы он открыл свое собственное окно терминала в любом из трех случаев и прикрепил wcout к этому окну терминала. Я хочу, чтобы это было сделано самой программой с помощью системных вызовов C ++, а не путем выполнения программы из какой-либо оболочки или скрипта. Потому что тогда выполнение в IDE Studio и двойной щелчок в файловом менеджере все равно будут иметь тот же эффект.

Быть программистом Windows, что кажется мне вполне естественным, но я не мог понять, как это делается ни в моих книгах по Unix, ни в Интернете. Я запрашиваю не то, действительно ли это так сложно сделать, или я что-то упускаю?

Ответы [ 4 ]

5 голосов
/ 03 апреля 2012

Следующее близко к тому, что вы хотите. В ней все еще есть несколько ошибок:

  • xterm не может быть нормально закрыт (хотя он закрывается, когда программа завершается). Понятия не имею, почему это так.
  • Перед намеченным выводом выводится число. Опять же, я понятия не имею, почему.
  • Кажется, я не могу перенаправить ввод.

Может быть, кто-то еще знает, как исправить эти ошибки (и любые другие, которые я, возможно, не заметил).

#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <sstream>

int main()
{
  int pt = posix_openpt(O_RDWR);
  if (pt == -1)
  {
    std::cerr << "Could not open pseudo terminal.\n";
    return EXIT_FAILURE;
  }
  char* ptname = ptsname(pt);
  if (!ptname)
  {
    std::cerr << "Could not get pseudo terminal device name.\n";
    close(pt);
    return EXIT_FAILURE;
  }

  if (unlockpt(pt) == -1)
  {
    std::cerr << "Could not get pseudo terminal device name.\n";
    close(pt);
    return EXIT_FAILURE;
  }

  std::ostringstream oss;
  oss << "xterm -S" << (strrchr(ptname, '/')+1) << "/" << pt << " &";
  system(oss.str().c_str());

  int xterm_fd = open(ptname,O_RDWR);
  char c;
  do read(xterm_fd, &c, 1); while (c!='\n');

  if (dup2(pt, 1) <0)
  {
    std::cerr << "Could not redirect standard output.\n";
    close(pt);
    return EXIT_FAILURE;
  }
  if (dup2(pt, 2) <0)
  {
    std::cerr << "Could not redirect standard error output.\n";
    close(pt);
    return EXIT_FAILURE;
  }

  std::cout << "This should appear on the xterm." << std::endl;
  std::cerr << "So should this.\n";
  std::cin.ignore(1);

  close(pt);
  return EXIT_SUCCESS;
}
3 голосов
/ 03 апреля 2012

Вы хотите вывести в файл (перенаправить, используя API ведения журнала или закрыть стандартный вывод / открыть его как файл).Затем добавьте tail -f в выбранном вами терминале.

Это добавило преимущество сохранения выходных данных журнала для проверки, даже если терминал выходит из строя / уничтожается.

0 голосов
/ 03 апреля 2012

Я бы порекомендовал создать скрипт оболочки, который запускает терминал, которому вы передаете свою программу для выполнения, затем вам следует вызвать этот скрипт вместо вашей программы из файлового менеджера.

Ваш скрипт.sh:

#! / Bin / ш

xterm -e / path_to_your_program / your_program

0 голосов
/ 03 апреля 2012

Когда вы вызываете вашу программу, вместо запуска: myprog 1 2 3 a b c, запустите xterm -e myprog 1 2 3 a b c.

...