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]
나는 두 번째 버전이 첫 번째 버전과 동일하게 작동하기를 원합니다. 단지 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