Вихідні послідовності у виведенні сценарію, викликаного з ncurses програми


14

Я зараз запускаю mcabber як мій клієнт Jabber (який використовує ncurses) під час сеансу tmux на своєму домашньому сервері. Локально я запускаю iTerm2 як емулятор терміналу, який підтримує запускання сповіщень про гарчання через послідовності втечі символів.

Примітка. У echoцьому питанні все працює на зразок printf %b, або echo -eв bash та GNU echo.

наприклад, echo "\e]9;foobar\007"змушує iTerm2 надсилати повідомлення Growl з текстом "foobar".

Однак, коли в tmux сеансі послідовності втечі з'їдаються. Тому використання захищеної символьної послідовності символів \Ptmuxможна використовувати так:

echo "\ePtmux;\e\e]9;foobar\007\e\\"

Це запускає бурчання повідомлення протягом сеансу tmux.

Однак, коли я використовую це в моєму сценарії подій mcabber, який звільняється, коли надходить нове повідомлення, повідомлення не запускається, ніби відлуння надсилається на неправильний термінал.

Я вважаю, що це пов'язано з тим mcabber, який запускає скрипт, є додатком ncurses, тому вихід з мого звичайного сценарію bash втрачається, і iTerm 2 ніколи його не бачить.

Я також намагався зателефонувати smcup без успіху, перш ніж повторюватися згідно з деякими я знайденими ідеями

tput smcup
echo "\ePtmux;\e\e]9;$FROM: $MSG\007\e\\"
tput rmcup

Я припускаю, що це не працює, оскільки проблема полягає не в тому, щоб повернутися до «реального вікна терміналу», а більше направити висновок у вікно ncurses.

Будь-які ідеї на цьому?

Відповіді:


1

Причина, по якій сценарій події не вдається надіслати повідомлення "зростання", полягає в тому, що mcabberзакриває стандартні потоки вводу, виводу та помилок, коли він виконує команду події. Ви можете побачити це в hooks.c:

  if ((pid=fork()) == -1) {
    scr_LogPrint(LPRINT_LOGNORM, "Fork error, cannot launch external command.");
    g_free(datafname);
    return;   
  }    
  if (pid == 0) { // child
    // Close standard file descriptors
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    if (execl(extcmd, extcmd, arg_type, arg_info, bjid, arg_data,
              (char *)NULL) == -1) {
      // scr_LogPrint(LPRINT_LOGNORM, "Cannot execute external command.");
      exit(1);
    }
  }
  g_free(datafname);

Це робить сценарій події запущеним, не втручаючись у потоки, якими користується mcabber.

Не існує спеціального режиму ncurses, що перехоплює повідомлення (адже tmuxвін вже працює як додаток terminfo). Ви, ймовірно, можете вирішити проблему, перенаправивши echo(бажано printf) на /dev/tty, наприклад,

#!/bin/sh
printf '\033Ptmux;\033\033]9;foobar\007\033\\' >/dev/tty

0

Програми tmux і screen не проходять безпосередньо через послідовності втечі. Вони представляють додаток одного типу терміналу (тип терміналу екрана), а сам додаток ncurses до іншого терміналу. Фактично це щось на зразок термінального перекладача. Так, так, він споживає (або відкидає) послідовності для типу "екран" терміналу, і створює буфер, який ви бачите. Потім він бере ці події зміни буфера і використовує будь-який тип терміналу, який ви використовуєте для відображення поточного буфера. Тож оригінальний додаток та переглядач терміналу роз’єднані.


0

Якби ти поставив щось на кшталт ...

export "PTTY=$(tty)"

... у вашій /etc/profileтоді для кожної нової -lоболонки ogin ви б викликали (що зазвичай відбувається, коли ви відкриваєте нове вікно терміналу), що змінна середовища буде доступна для всіх її дочірніх процесів - які повинні включати tmuxі всіх її дітей .

Це повинно дати вам можливість зробити ...

printf '\033]9;foobar\007' >"$PTTY"

... і тим самим пропустити прямо через будь-які ptyшари, які можуть існувати між вашою поточною оболонкою та емулятором терміналу, який ви використовуєте.


0

Якщо проблема полягає в тому, що вихід з вашого bash скрипту втрачається, ви можете виграти битву з перенаправленням:

echo "\ ePtmux; \ e \ e] 9; foobar \ 007 \ e \"> / dev / tty

Однак я підозрюю, що справжня проблема полягає в тому, що ви повинні використовувати echo -eтак, щоб bash обробляв послідовності втечі у вашому рядку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.