2016-03-10 3 views
1

У меня есть эта программа, которая используеттерминал ширина IOCTL, когда по трубопроводу до менее

ioctl(file_descriptor_of_stdout, TIOCGWINSZ, &w); 

, чтобы получить концевую ширину (используется в печатных массивов). Это отлично работает, если я запускаю свою программу непосредственно на терминале; Тем не менее, я часто выхожу на выходе через меньше, для подкачки и поиска. Для обсуждения предположим, что stderr также передается по каналам, поэтому я не могу «обмануть», ожидая, что на самом деле перейдем к терминалу.

Теперь, сам по себе делает с учетом ширины терминала - для разрыва линий или измельчения их. Разве она не передает эту информацию так или иначе, как она проходит через нее?

+0

Вы можете вносить изменения в программу, чтобы использовать '' fd' из/Dev/tty', а чем 'stdout' –

+0

@MarkSetchell:. Мда И/DEV/tty отличается для каждого процесса в зависимости от того, на каком терминале он включен? – einpoklum

+0

Да, это правильно. Оно специфично для каждого процесса. –

ответ

2

У вас есть более чем один выбор:

  • есть три потока ( стандартного устройства ввода, стандартного вывод и STDERR), которые ваша программа может проверить с помощью isatty(fileno(stdin)) и т.д. Перенаправление вывода для интерактивного программа чаще выполняется, чем перенаправление ввода, поэтому стоит проверить это.
  • Если ни один из потоков не является терминалом, вы можете открыть tty, который связан с каждым взаимодействием. Это не обязательно /dev/tty, как показано на быстрой проверки от бега оболочки в xterm:
 
    $ ls -l /dev/tty;tty;ls -l `tty` 
    crw-rw-rw- 1 root root 5, 0 Mar 10 15:46 /dev/tty 
    /dev/pts/1 
    crw--w---- 1 tom tty 136, 1 Mar 10 16:09 /dev/pts/1 
  • POSIX документы программу tty, которая может показаться, что хорошее место, чтобы начать. Однако ваша программа должна будет прочитать имя пути из канала (немного сложнее, чем isatty, применяемого к стандартным потокам). В документации также указано:

    Если входной сигнал не считывается со стандартного ввода, стандартный вход должен быть проверен, чтобы определить, является ли он терминалом, и если да, то определить имя терминала.

    То есть, если стандартный ввод вашей программы перенаправлен (не терминал), tty не поможет найти настоящий терминал.
    Комментарий от @einpoklum напомнил мне, что POSIX также документирует звонок библиотеки ttyname. Кстати, обычно, когда программа реализуется определенным вызовом функции, POSIX документирует программу, говоря, что она ведет себя «как если», если она использовала этот вызов. Но он не упомянул об этом для tty.

  • Если ни один из стандартных потоков не является терминалом, вы: может попробуйте открыть /dev/tty. Если ваша программа не является интерактивной, это может быть неудачно, например, работает в cron или в фоновом режиме. Чтобы это не показалось странной критикой, есть случайные просьбы открыть приложение X от cron. Опять же, POSIX документы (в 10.1 Directory Structure and Files
+0

POSIX tty не является хорошим местом для запуска, он просто вызывает вызов библиотеки 'ttyname()' и выводит результат (я проверил источники). Но попытка всех 3 дескрипторов файлов - неплохая идея. – einpoklum