ECLのLinux stdioをリダイレクトして、埋め込まれているアプリケーションとストリームを共有しないようにすることができるかどうか疑問に思っていました.
私の問題は、ホスト アプリケーションが独自の目的で stdin、stdout、および stderr を引き継ぐことです。そこで、Lisp ノイズ用と、SLIME/SWANK がクラッシュしてトップレベルに戻ったときの回復用に別のコンソールを用意したいと思います。現在、SWANK hiccup はCL-USER>
プロンプトをアプリケーションのデバッグ ログに記録しC opperation (read) signalled an error
、stdout による失敗はリダイレクトされ、stdin はクローズされているか、親プロセスによって使用されている可能性が高いです。
などを新しいストリームにできることは知っていますがsetf *standand-output*
、screen、xterm、socket などの端末をそれに接続する方法が見つかりませんでした。基礎となる Linux/C ファイル記述子が必要で、それから PTY を作成できます。
telnetを使用して接続できるソケットサーバーに標準ストリームを接続する方法があれば、さらに良いでしょう。
アップデート
コメントの提案に従って、次のコードを試しました。
(loop for filename in '("stdin-fifo" "stdout-fifo" "stderr-fifo") do
(let (
(truename (probe-file filename)))
(if truename nil
(ext:run-program "/usr/bin/mkfifo" (list filename)))))
(setf *standard-output*
(open (probe-file "stdout-fifo") :direction :output :if-exists :overwrite))
(setf *error-output*
(open (probe-file "stderr-fifo") :direction :output :if-exists :overwrite))
(setf *standard-input*
(open (probe-file "stdin-fifo") :direction :input))
それはまったく仕事をしません。問題は、IO の一部が SWANK にリダイレクトされている間、実際のストリームを取得する方法がまだあるように見えることです。SWANKがどのようにそれを行うかを理解するには、ある程度の調査が必要になると思います. ああ、便利さの代償!
更新 2
私の間違い。*standard-error*
しかありません*error-output*
。私が Lisp の初心者だと言えますか?
これで、すべてがリダイレクトされました。しかし、SLIMEはSWANKに話しかけなくなり、やや目的を果たせず……。
アップデート 3
勝利!SLIME を接続する前に、ターミナルで次のシェル スクリプトのようなものを実行して、最上位シェルを作成する必要があります。
tail -f stdout-fifo &
tail -f stderr-fifo &
cat - >> stdin-fifo
理由は、推測できません。しかし幸いなことに、とにかく機能します。
ところで、より良い回答を投稿したい人を落胆させないでください
誰かがストリームを監視しているかどうかにかかわらず、ストリームを維持するソケット サーバーまたは画面分離型 PTY を作成できると確信しています。それははるかに洗練されたソリューションになります。