tty入力が必要なプログラムの出力を変更する必要があります。プログラムの出力をユーティリティ(たとえばsed
)にパイプすると、入力行は表示されません。
具体的で簡単な例として、REPLプロンプトを含む一般的なScala入力を使用したいと思います。
$ scala
Welcome to Scala 2.12.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.
scala>
すべての項目をJava
次に変更しますMocha
。
$ scala | sed 's/Java/Mocha/g'
Welcome to Scala 2.12.3 (Mocha HotSpot(TM) 64-Bit Server VM, Mocha 1.8.0_60).
Type in expressions for evaluation. Or try :help.
問題は、scala>
最後の行()と入力したキーボード入力がを押すまで表示されないことです。[Enter]
私は2番目のバージョンが最初のバージョンと同じように動作したいと思います。sed
単に置き換え(もちろんキーボード入力を置き換えるわけではありません)しかありません。可能ですか?
(もちろん、ポータブルソリューションが最善ですが、唯一のソリューションがシェルまたはディストリビューション専用の場合は、ZshとBSDを好みます。ありがとうございます。)
答え1
パイプによってブロックベースのバッファリングが使用される可能性があるため、バッファリングが問題になりますscala
(デフォルトの端末回線ベースのバッファリングの代わりに参照)。setvbuf(3)
)とsed
バッファリング(またはパイプラインの他のエントリ)が実行されます。stdbuf
すべてに適用して移植性を捨て、サルパッチが機能することを望むかもしれませんLD_PRELOAD
。別のオプションは、PTYでREPLを実行し、ユーザー入力を提供し、出力を送信する前に置き換えることです。ここに示されているSBCLはscala
私のコンピュータではまったく機能しません。
$ ./mochanichize sbcl
This is SBCL 1.3.20, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (print "Java")
"Mocha"
"Mocha"
* (exit)
$
そしてコードmochanichize
。
#!/usr/bin/env expect
package require Tcl 8.5
proc mochanichize {fh} {
global godot
set somedata [read $fh]
if {[eof $fh]} { close $fh; set godot 1; return; }
regsub -all {\mJava\M} $somedata {Mocha} somedata
puts -nonewline $somedata
}
proc sendtoprog {from to} {
# TODO support ^D but that's more complicated
puts -nonewline $to [read $from]
}
# no echo on PTY command we're running (soas not to duplicate what is
# echo'd back to the user via the user tty)
set stty_init -echo
if {[catch {spawn -noecho {*}$argv} err]} { puts stderr $err; exit 1 }
chan configure $spawn_id -blocking 0 -buffersize 1
chan event $spawn_id readable [list mochanichize $spawn_id]
chan configure stdin -blocking 0 -buffersize 1
chan configure stdout -blocking 0 -buffersize 1
chan event stdin readable [list sendtoprog stdin $spawn_id]
# TODO better handle ^Z this goes all meh on it
trap SIG_IGN SIGTSTP
vwait godot