GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Accepting-Output.html ・ emacs-doc.conao3.com

41.9.4 プロセスからの出力の受け取り

非同期サブプロセスからの出力は、通常、経過時間やターミナル入力といった何らかの外部イベントをEmacsが待機している間にのみ届きます。Lispプログラムにおいては、特定の時点で出力が届くことを明示的に許可したり、あるいはプロセスから出力が届くまで待機したりすることが有用な場合があります。

関数: accept-process-output &optional process seconds millisec just-this-one

この関数により、Emacsはプロセスからの保留中の出力を読み取ることができます。出力は、プロセスによって設定されたフィルタ関数に渡されます(プロセスフィルタ関数を参照)。process が nil 以外の場合、この関数は process から何らかの出力を受信するか、または process が接続を閉じるまで戻りません。

引数 seconds と millisec を使用すると、タイムアウト期間を指定できます。前者は秒単位で、後者はミリ秒単位で期間を指定します。このように指定された2つの期間は合算され、サブプロセスの出力がない場合でも、accept-process-output はその時間が経過した後に戻ります。

引数 millisec は廃止されており(使用すべきではありません)、seconds で浮動小数点数を指定することで、小数秒の待機を指定できるためです。seconds が 0 の場合、関数は保留中の出力を何でも受け取りますが、待機は行いません。

process がプロセスであり、引数 just-this-one が nil 以外である場合、そのプロセスからの出力のみが処理され、当該プロセスから何らかの出力を受信するかタイムアウトが発生するまで、他のプロセスからの出力は一時停止されます。just-this-one が整数である場合は、タイマーの実行も抑制されます。この機能は一般的に推奨されませんが、音声合成などの特定のアプリケーションでは必要となる場合があります。

関数 accept-process-output は、process から出力があった場合、または process が nil である場合に任意のプロセスから出力があった場合に、non-nil を返します。これは、対応する接続にバッファリングされたデータが含まれている場合、プロセスが終了した後でも発生することがあります。タイムアウトが経過した場合、または出力が届く前に接続が閉じられた場合、この関数は nil を返します。

なお、この関数は、サブプロセスから何らかの出力が得られ次第直ちに復帰することが保証されているわけではありません。というのも、この関数の主な目的はEmacsにサブプロセスからの出力を読み取らせることであり、可能な限り待機時間を短くすることではないからです。特に、process が nil である場合、指定されたタイムアウトが経過するまで関数が復帰することはないと想定すべきです。したがって、Lispプログラムでサブプロセスの出力待ち時間を最小限に抑える必要がある場合は、特定の process に対して nil 以外の値を指定してこの関数を呼び出す必要があります。

プロセスからの接続にバッファリングされたデータが含まれている場合、プロセスが終了した後でも accept-process-output は nil 以外を返すことがあります。したがって、以下のループは:

;; This loop contains a bug.
(while (process-live-p process)
  (accept-process-output process))

process からの出力をすべて読み込んでしまうことが多く、レースコンディションが発生するため、接続にまだデータが残っている状態で process-live-p が nil を返すと、一部の出力を見逃す可能性があります。ループは次のように記述するのがより適切です:

(while (accept-process-output process))

nil stderr 以外のプロセスを make-process に渡した場合、そのプロセスには標準エラー出力処理が設定されます。非同期プロセスの作成 を参照してください。この場合、メインプロセスからプロセス出力を待機しても、標準エラー出力処理からの出力は待機されません。プロセスから標準出力と標準エラー出力の両方を確実に受け取るには、以下のコードを使用してください。

(while (accept-process-output process))
(while (accept-process-output stderr-process))

make-process の stderr 引数にバッファを渡した場合でも、次のように標準エラー出力プロセスを待機する必要があります。

(let* ((stdout (generate-new-buffer "stdout"))
       (stderr (generate-new-buffer "stderr"))
       (process (make-process :name "test"
                              :command '("my-program")
                              :buffer stdout
                              :stderr stderr))
       (stderr-process (get-buffer-process stderr)))
  (unless (and process stderr-process)
    (error "Process unexpectedly nil"))
  (while (accept-process-output process))
  (while (accept-process-output stderr-process)))

両方の accept-process-output フォームが nil を返す場合にのみ、プロセスが終了し、Emacs がその出力をすべて読み込んだことが確実になります。

この方法では、リモートホスト上で動作しているプロセスから保留中の標準エラーを読み取ることはできません。