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

41.3 同期プロセスの作成

同期プロセスが作成された後、Emacsはプロセスが終了するのを待ってから処理を続行します。GNUやUnix32でDiredを起動するのがその例です。これはlsを同期プロセスで実行し、その後出力をわずかに変更します。プロセスが同期であるため、Emacsが何らかの処理を試みる前に、ディレクトリ一覧全体がバッファに届きます。

Emacsが同期サブプロセスの終了を待機している間、ユーザーは C-g と入力することで終了できます。最初の C-g は SIGINT シグナルでサブプロセスを強制終了しようとしますが、実際にサブプロセスが終了するまで待機してから終了します。その間にユーザーが別の C-g を入力すると、SIGKILL によってサブプロセスが即座に強制終了され、直ちに終了します(ただし、他のプロセスの強制終了が機能しない MS-DOS を除きます)。終了 を参照してください。

同期サブプロセス関数は、プロセスがどのように終了したかを示す情報を返します。

同期サブプロセスからの出力は、一般的にファイルから読み込まれるテキストと同様に、符号化方式を用いてデコードされます。call-process-region によってサブプロセスに送信される入力は、ファイルに書き込まれるテキストと同様に、符号化方式を用いて符号化されます。符号化方式を参照してください。

関数: call-process program &optional infile destination display &rest args

この関数はprogramを呼び出し、その完了を待ちます。

サブプロセスの現在の作業ディレクトリは、現在のバッファの値がローカルである場合(unhandled-file-name-directory で判定)は default-directory に、そうでない場合は "~" に設定されます。リモートディレクトリでプロセスを実行したい場合は、process-file を使用してください。

新しいプロセスの標準入力は、infile が nil でない場合はファイル infile から、そうでない場合はヌルデバイスから供給されます。引数 destination は、プロセスの出力先を指定します。指定可能な値は以下の通りです:

バッファ

そのバッファのポイントより前の出力を挿入します。これには、プロセスの標準出力ストリームと標準エラーストリームの両方が含まれます。

バッファ名(文字列)

出力を、ポイントより前の同名のバッファに挿入します。

t

現在のバッファのポイント前に、出力を挿入します。

nil

出力を破棄してください。

0

出力を破棄し、サブプロセスの終了を待たずに直ちに nil を返す。

この場合、Emacsと並列に実行される可能性があるため、処理は厳密には同期的ではありません。しかし、この関数が戻った時点でEmacsは実質的にサブプロセスの処理を完了しているため、同期的であると考えて差し支えありません。

MS-DOSは非同期サブプロセスをサポートしていないため、このオプションは動作しません。

(:file file-name)

出力を指定したファイル名に、既に存在する場合は上書きして送信します。

(real-destination error-destination)

標準出力ストリームと標準エラー出力ストリームは分けて管理し、通常の出力はreal-destinationで指定された通りに処理し、エラー出力はerror-destinationに従って処理してください。error-destinationがnilの場合はエラー出力を破棄することを意味し、tは通常出力と混在させることを意味し、文字列はエラー出力のリダイレクト先となるファイル名を指定します。

エラー出力先のバッファを直接指定することはできません。実装が非常に困難だからです。ただし、エラー出力を一時ファイルに書き出し、サブプロセスの終了時にそのファイルをバッファに挿入することで、同様の結果を得ることができます。

display が nil 以外の場合、call-process は出力が挿入されるたびにバッファを再表示します。(ただし、出力のデコードに選択されたコーディング方式が undecided(実際のデータからエンコーディングを推論する方式)である場合、非ASCII文字が出現すると、再表示が継続できなくなることがあります。これを修正するのが困難な根本的な理由があります。プロセスからの出力の受信 を参照してください。)

そうでない場合、関数 call-process は再表示を行わず、通常の処理過程で Emacs がそのバッファを再表示したときに初めて、結果が画面上に現れます。

残りの引数 args は、プログラムのコマンドライン引数を指定する文字列です。各文字列は、個別の引数として program に渡されます。

call-process が返す値(待機しないよう指定した場合を除く)は、プロセスが終了した理由を示します。数値はサブプロセスの終了ステータスを表し、0 は成功、それ以外の値は失敗を意味します。プロセスがシグナルによって終了した場合、call-process はそのシグナルを説明する文字列を返します。call-process に待機しないよう指定した場合は、nil を返します。

以下の例では、バッファ ‘foo’ がカレントです。

(call-process "pwd" nil t)
     ⇒ 0

---------- Buffer: foo ----------
/home/lewis/manual
---------- Buffer: foo ----------

(call-process "grep" nil "bar" nil "lewis" "/etc/passwd")
     ⇒ 0

---------- Buffer: bar ----------
lewis:x:1001:1001:Bil Lewis,,,,:/home/lewis:/bin/bash

---------- Buffer: bar ----------

かつて insert-directory 関数の定義に見られた call-process の使用例を以下に示します。

(call-process insert-directory-program nil t nil switches
              (if full-directory-p
                  (concat (file-name-as-directory file) ".")
                file))
関数: process-file program &optional infile buffer display &rest args

この関数は、別プロセスでファイルを同期的に処理します。call-process と同様ですが、サブプロセスのカレントワーキングディレクトリを指定する変数 default-directory の値に基づいて、ファイル名ハンドラを呼び出す場合があります。

引数の扱いは call-process とほぼ同様ですが、以下の点が異なります。

一部のファイル名ハンドラでは、引数 infile、buffer、および display のすべての組み合わせや形式をサポートしていない場合があります。例えば、実際に渡された値にかかわらず、display を nil であるかのように動作するファイル名ハンドラもあります。また別の例として、buffer 引数を用いて標準出力とエラー出力を分離することをサポートしていないファイル名ハンドラもあります。

ファイル名ハンドラが呼び出されると、第1引数 program に基づいて実行するプログラムが決定されます。例えば、リモートファイル用のハンドラが呼び出されたとします。その場合、プログラムの検索に使用されるパスは exec-path とは異なる可能性があります。

第2引数 infile では、ファイル名ハンドラを呼び出すことができます。このファイル名ハンドラは、process-file 関数自体に選択されたハンドラとは異なる場合があります。(例えば、default-directory はあるリモートホストに、infile は別のリモートホストにある場合があります。あるいは、default-directory は特殊ではない一方、infile はリモートホストにある場合もあります。)

buffer が (real-destination error-destination) 形式のリストであり、error-destination がファイル名である場合、infile の場合と同様の注意点が適用されます。

残りの引数 (args) は、そのままプロセスに渡されます。args に含まれるファイル名の処理に Emacs は関与しません。混乱を避けるため、args では絶対ファイル名を避け、代わりにすべてのファイル名を default-directory を基準とした相対パスで指定するのが最善でしょう。このような相対ファイル名を構築するには、関数 file-relative-name が便利です。あるいは、file-local-name(特定のファイル名を「マジック」にする を参照)を使用して、リモートホストから見た絶対ファイル名を取得することもできます。

変数: process-file-side-effects

この変数は、process-file の呼び出しによってリモートファイルが変更されるかどうかを示します。

デフォルトでは、この変数は常に t に設定されており、process-file を呼び出すとリモートホスト上の任意のファイルが変更される可能性があります。nil に設定すると、ファイル名ハンドラはリモートファイル属性のキャッシュに関して動作を最適化できます。

この変数を変更する際は、必ず let 束縛を用い、setq は絶対に使用しないでください。

ユーザーオプション: process-file-return-signal-string

このユーザーオプションは、process-file の呼び出しが、リモートプロセスを中断したシグナルを説明する文字列を返すかどうかを示します。

プロセスが128を超える終了コードを返した場合、それはシグナルとして解釈されます。process-fileは、このシグナルを説明する文字列を返す必要があります。

このルールに違反する処理が存在するため、シグナルに紐付けられていない128を超える終了コードを返す場合、process-fileはリモートプロセスに対して常にその終了コードを自然数として返します。このユーザーオプションをnon-nilに設定すると、process-fileはこうした終了コードをシグナルとして解釈し、それに対応する文字列を返すようになります。

関数: call-process-region start end program &optional delete destination display &rest args

この関数は、startからendまでのテキストを、programを実行中のプロセスに標準入力として送信します。deleteがnil以外の場合は送信したテキストを削除します。これは、destinationがtである場合に、入力の代わりに出力を現在のバッファに挿入する際に有用です。

引数 destination と display は、サブプロセスからの出力の処理方法と、出力が届くたびにディスプレイを更新するかどうかを制御します。詳細については、上記の call-process の説明を参照してください。destination が整数 0 の場合、call-process-region は出力を破棄し、サブプロセスの終了を待たずに直ちに nil を返します(これは非同期サブプロセスがサポートされている場合にのみ動作します。つまり、MS-DOS では動作しません)。

残りの引数 args は、プログラムのコマンドライン引数を指定する文字列です。

call-process-region の戻り値は call-process と同様です。待機せずに返すよう指定した場合は nil となり、それ以外の場合は、サブプロセスがどのように終了したかを示す数値または文字列となります。

以下の例では、call-process-region を使用して cat ユーティリティを実行しており、標準入力はバッファ ‘foo’(単語 ‘input’)の先頭5文字となっています。cat は標準入力を標準出力にコピーします。引数 destination が t であるため、この出力が現在のバッファに挿入されます。

---------- Buffer: foo ----------
input∗
---------- Buffer: foo ----------

(call-process-region 1 6 "cat" nil t)
     ⇒ 0

---------- Buffer: foo ----------
inputinput∗
---------- Buffer: foo ----------

例えば、shell-command-on-region コマンドは、次のような形で call-shell-region を使用します。

(call-shell-region
 start end
 command              ; shell command
 nil                  ; do not delete region
 buffer)              ; send output to buffer
関数: call-process-shell-command command &optional infile destination display

この関数は、シェルコマンド command を同期的に実行します。その他の引数は call-process と同様に扱われます。従来の呼び出し規約では、display の後に任意の数の追加引数を渡すことができ、それらは command に連結されていました。この方式は現在もサポートされていますが、強く非推奨とされています。

関数: process-file-shell-command command &optional infile destination display

この関数は call-process-shell-command と同様ですが、内部的には process-file を使用します。default-directory に応じて、command をリモートホスト上でも実行できます。従来の呼び出し規約では、display の後に任意の数の追加引数を渡すことができ、それらは command に連結されていました。この仕様は現在もサポートされていますが、強く非推奨とされています。

関数: call-shell-region start end command &optional delete destination

この関数は、start から end までのテキストを、command を実行している下位シェルに標準入力として送信します。この関数は call-process-region と同様ですが、プロセスがシェルである点が異なります。引数 delete、destination および戻り値は call-process-region と同様です。なお、この関数は追加の引数を受け付けません。

command がシェルを指定している場合(例:shell-file-name 経由)、コマンドを標準入力にパイプで渡した際の各種シェルの挙動は、シェルやシステムに依存し、したがって移植性がないことに留意してください。こうした差異は、リージョンに複数行が含まれる場合、すなわち改行を含むコマンドをシェルにパイプで渡す場合に特に顕著になります。そのため、この手法を用いる Lisp プログラムでは、シェルの仕様に合わせて、リージョン内のテキストを異なる形式でフォーマットする必要があります。

関数: shell-command-to-string command

この関数は command(文字列)をシェルコマンドとして実行し、その出力を文字列として返します。command に実際に複数のコマンドが含まれている場合、その動作は呼び出されるシェルに依存します(ローカルコマンドの場合は shell-file-name によって決定されます)。特に、MS-Windows ではコマンド間の区切り文字に改行を使用できません。代わりに ‘&&’ を使用してください。

関数: process-lines program &rest args

この関数は program を実行して終了を待ち、その出力を文字列のリストとして返します。リスト内の各文字列にはプログラムが出力した1行のテキストが格納されており、各行から改行文字は除去されています。program、args 以降の引数は、プログラムの実行に使用するコマンドライン引数を指定する文字列です。

program が 0 以外の終了ステータスで終了した場合、この関数はエラーを通知します。

この関数は call-process を呼び出すことで動作するため、プログラムの出力は call-process と同様にデコードされます。

関数: process-lines-ignore-status program &rest args

この関数は process-lines と同様ですが、program がゼロ以外の終了ステータスで終了してもエラーを報告しません。


脚注

(32)

他のシステムでは、EmacsはlsのLispエミュレーションを使用しています。ディレクトリの内容を参照してください。