現在、ホームサーバーの tmux セッションで、mcabber を Jabber クライアント (ncurses を使用) として実行しています。ローカルでは、文字エスケープ シーケンスによる growl 通知のトリガーをサポートする iTerm2 をターミナル エミュレーターとして実行しています。
注:echo
この質問の はすべて、 bash および GNU の 、printf %b
または のように機能します。echo -e
echo
たとえば、echo "\e]9;foobar\007"
iTerm2 は「foobar」というテキストを含む Growl メッセージを送信します。
ただし、tmux セッションでは、エスケープ シーケンスが消費されます。そのため、独自の文字エスケープ シーケンスを\Ptmux
次のように使用できます。
echo "\ePtmux;\e\e]9;foobar\007\e\\"
これにより、tmux セッション内から growl メッセージがトリガーされます。
ただし、新しいメッセージが受信されたときに起動される 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
、すでにecho
terminfo アプリケーションとして実行中)。おそらく、 (できればprintf
) を にリダイレクトすることで問題を回避できるでしょう/dev/tty
。たとえば、
#!/bin/sh
printf '\033Ptmux;\033\033]9;foobar\007\033\\' >/dev/tty
答え2
tmux および screen プログラムは、エスケープ シーケンスを直接渡しません。アプリケーションに 1 種類のターミナル (screen ターミナル タイプ) を提示し、それ自体が別のターミナルに対する ncurses アプリケーションです。実質的には、ターミナル トランスレータのようなものです。つまり、"screen" ターミナル タイプのシーケンスを消費 (または破棄) し、表示されるバッファーを作成します。次に、それらのバッファー変更イベントを取得し、現在使用しているターミナルの種類を使用して現在のバッファーを表示します。そのため、元のアプリと表示ターミナルは分離されています。
答え3
たとえば次のようなものを置くとします...
export "PTTY=$(tty)"
.../etc/profile
その後、新しい-l
Oginシェルを呼び出すたびに(これは、新しいターミナル ウィンドウを開いたときに通常発生することです)tmux
その環境変数は、そのすべての子プロセス(そのすべての子を含む)で使用できるようになります。
これにより、次のことが可能になります...
printf '\033]9;foobar\007' >"$PTTY"
...これにより、pty
現在のシェルと使用しているターミナル エミュレーターの間に存在する可能性のあるすべてのレイヤーをスキップします。
答え4
bash スクリプトからの出力が失われることが問題である場合は、リダイレクトによって解決できます。
echo "\ePtmux;\e\e]9;foobar\007\e\" > /dev/tty
しかし、実際の問題は、echo -e
bash が文字列内のエスケープ シーケンスを処理できるように、 を使用する必要があるということだと思います。