本節では、非同期プロセスの作成方法について説明します。非同期プロセスが作成されると、それはEmacsと並行して動作し、Emacsは以降の節で説明する関数を用いてそのプロセスと通信できます(プロセスへの入力送信およびプロセスからの出力受信を参照してください)。なお、プロセス間通信は部分的にしか非同期ではありません。Emacsがプロセスとの間でデータを送受信するのは、それらの関数が呼び出されたときのみです。
非同期プロセスは、pty(擬似端末)またはパイプのいずれかを介して制御されます。ptyとパイプのどちらを選択するかはプロセスの作成時に決定され、デフォルトでは変数process-connection-typeの値に基づいています(後述)。利用可能な場合、シェルモードのようにユーザーから見えるプロセスには、通常ptyの方が好ましいです。これは、プロセスとその子プロセス間でジョブ制御(C-c、C-zなど)が可能であることや、対話型プログラムがptyを端末デバイスとして扱うのに対し、パイプはこれらの機能をサポートしていないためです。しかし、Lispプログラムが内部目的で使用し(すなわち、サブプロセスとのユーザー対話を必要としない)、サブプロセスとLispプログラムの間で大量のデータをやり取りする必要がある場合には、パイプの方が効率的であるため、パイプを使用する方が適切なことが多いです。また、多くのシステムではptyの総数に制限があるため、不必要に消費しないことが望ましいです。
この関数は、非同期サブプロセスを起動するための基本的な低レベルプリミティブです。サブプロセスを表すプロセスオブジェクトを返します。後述するより高レベルな
start-process
と比較して、キーワード引数を受け付け、より柔軟であり、一度の呼び出しでプロセスフィルタやセンチネルを指定できます。
引数 args は、キーワードと引数のペアのリストです。キーワードを省略することは、常に値 nil を指定して記述することと同等です。意味を持つキーワードは以下の通りです:
:name nameプロセス名として文字列 name を使用し、この名前のプロセスが既に存在する場合は、name を(‘<1>’ などを付加して)一意になるように変更します。
:buffer bufferプロセスバッファとして buffer を使用してください。値が nil の場合、サブプロセスはどのバッファにも関連付けられません。
:command commandプロセスのコマンドラインとして command
を指定してください。この値は、プログラムの実行ファイル名で始まり、その後にプログラムに引数として渡す文字列が続くリストである必要があります。リストの最初の要素が
nil の場合、Emacs は新しい擬似端末 (pty) を開き、その入出力を buffer
に関連付けますが、実際にプログラムを実行することはありません。その場合、リストの残りの要素は無視されます。
:coding coding
coding
がシンボルの場合、接続とのデータの読み書きの両方に使用するコーディングシステムを指定します。coding
がコンスセル (decoding . encoding) の場合、読み取りには decoding が、書き込みには encoding
が使用されます。プログラムに書き込まれるデータのエンコードに使用されるコーディングシステムは、コマンドライン引数のエンコードにも使用されます(ただし、プログラム自体は例外で、ファイル名は他のファイルと同様にエンコードされます。file-name-coding-system
を参照してください)。
coding が nil
の場合、コーディングシステムを特定するためのデフォルトルールが適用されます。デフォルトのコーディングシステムを参照してください。
:connection-type type
サブプロセスとの通信に使用するデバイスの種類を初期化します。指定可能な値は、ptyを使用する場合はpty、パイプを使用する場合はpipe、process-connection-type変数の値から導出されるデフォルトを使用する場合はnilです。typeがコンスセル(input . output)である場合、標準入力にはinputが、標準出力にはoutput(:stderrがnilの場合は標準エラー出力にも)が使用されます。
pty が利用できないシステム (MS-Windows) では、このパラメータは無視され、無条件にパイプが使用されます。
:noquery query-flagプロセスクエリフラグをquery-flagに初期化します。終了前のクエリを参照してください。
:stop stopped指定された場合、stopped は nil
である必要があり、nil 以外の値を使用することはエラーとなります。それ以外の場合、:stop
キーは無視され、パイププロセスなどの他のプロセスタイプとの互換性のために保持されます。非同期サブプロセスが停止状態で開始されることはありません。
:filter filterプロセスフィルタを filter に初期化します。指定しない場合はデフォルトのフィルタが提供され、後で上書きすることも可能です。プロセスフィルタ関数を参照してください。
:sentinel sentinelプロセスセンティネルを sentinel に初期化します。指定しない場合はデフォルトのセンティネルが使用され、後で上書きすることも可能です。センティネル:プロセスステータスの変更検出を参照してください。
:stderr stderrアソシエート stderr をプロセスの標準エラー出力に関連付けます。nil 以外の値は、後述する make-pipe-process で作成されたバッファまたはパイププロセスである必要があります。stderr が nil
の場合、標準エラー出力は標準出力と混合され、両者が buffer または filter に送られます。
stderr がバッファである場合、Emacs はパイププロセスである 標準エラープロセス を作成します。このプロセスには、デフォルトのフィルタ(プロセスフィルタ関数 を参照)、センチネル(センチネル:プロセス状態の変化の検出 を参照)、およびコーディングシステム(デフォルトのコーディングシステム
を参照)が設定されます。一方で、query-flag を終了時クエリフラグ(終了前のクエリ
を参照)として使用します。また、このプロセスは stderr バッファ(プロセスバッファ
を参照)に関連付けられ、その出力(メインプロセスの標準エラー)をそこに送信します。標準エラープロセスのプロセスオブジェクトを取得するには、stderr バッファを get-buffer-process
に渡します。
stderr がパイププロセスである場合、Emacs はそれを新しいプロセスの標準エラープロセスとして使用します。
:file-handler file-handlerfile-handler が nil
でない場合は、現在のバッファの default-directory
に対応するファイル名ハンドラを探し、そのファイル名ハンドラを呼び出して処理を行う。そのようなハンドラが存在しない場合は、file-handler が nil
であるものとして処理を進める。
実際の接続情報で修正された元の引数リストは、process-contact関数経由で利用可能です。
サブプロセスの現在の作業ディレクトリは、現在のバッファの値がローカルである場合(unhandled-file-name-directory で判定)は default-directory に、そうでない場合は ~
に設定されます。リモートディレクトリでプロセスを実行したい場合は、:file-handler t を
make-process に渡してください。その場合、現在の作業ディレクトリは default-directory のローカル名コンポーネント(file-local-name で判定)となります。
ファイル名ハンドラの実装によっては、生成されたプロセスオブジェクトに filter や sentinel を適用できない場合があります。:stderr
引数にパイププロセスを指定することはできず、ファイル名ハンドラはこの用途でのパイププロセスをサポートしていません。:stderr 引数としてのバッファは受け付けられ、その内容はパイププロセスを使用せずに表示されます。プロセスフィルタ関数、センチネル:プロセスステータス変更の検出、および プロセスからの出力の受理を参照してください。
一部のファイル名ハンドラでは make-process
をサポートしていない場合があります。その場合、この関数は何も行わず、nil を返します。
この関数は、子プロセスに接続可能な双方向パイプを作成します。これは make-process の
:stderr キーワードと併用すると便利です。この関数はプロセスオブジェクトを返します。
引数 args は、キーワードと引数のペアのリストです。キーワードを省略することは、常に値 nil で指定することと同等です。
意味のあるキーワードは以下の通りです:
:name nameプロセス名として文字列 name を使用してください。make-process と同様に、必要に応じて一意になるよう変更されます。
:buffer bufferプロセスバッファとして buffer を使用してください。値が nil の場合、サブプロセスはどのバッファにも関連付けられません。
:coding coding
coding がシンボルの場合、接続とのデータの送受信の両方で使用する符号化方式を指定します。coding がコンスセル (decoding . encoding) の場合、読み取りには decoding が、書き込みには encoding が使用されます。
coding が nil
の場合、コーディングシステムを特定するためのデフォルトルールが適用されます。デフォルトのコーディングシステムを参照してください。
:noquery query-flagプロセスクエリフラグをquery-flagに初期化します。終了前のクエリを参照してください。
:stop stoppedstopped が nil
以外の場合、停止状態でプロセスを開始します。停止状態では、パイププロセスは受信データを受け付けませんが、送信データを送ることは可能です。停止状態は
stop-process によって設定され、continue-process によって解除されます(プロセスへのシグナル送信 を参照)。
:filter filterプロセスフィルタを filter に初期化します。指定しない場合はデフォルトのフィルタが提供され、後で変更することも可能です。プロセスフィルタ関数を参照してください。
:sentinel sentinelプロセスセンティネルを sentinel に初期化します。指定しない場合はデフォルトのセンティネルが使用され、これは後で変更可能です。センティネル:プロセスステータスの変更検出を参照してください。
実際の接続情報で修正された元の引数リストは、process-contact関数経由で利用可能です。
この関数は make-process をラップした高レベル関数であり、call-process
と同様のインターフェースを提供します。新しい非同期サブプロセスを生成し、その中で指定された program
を実行します。Lisp における新しいサブプロセスを表すプロセスオブジェクトを返します。引数 name
はプロセスオブジェクトの名前を指定します。make-process
と同様に、必要に応じて一意な名前になるよう変更されます。バッファ buffer-or-name
は、プロセスに関連付けるバッファです。
program が nil の場合、Emacs
は新しい擬似端末 (pty) を開き、サブプロセスを作成することなく、その入出力を buffer-or-name に関連付けます。その場合、残りの引数 args は無視されます。
args の残りの部分は、サブプロセスのコマンドライン引数を指定する文字列です。
以下の例では、最初のプロセスが起動し、100秒間実行(正確にはスリープ)します(出力バッファ ‘foo’ が直ちに作成されます)。その間に、2番目のプロセスが起動し、一意性を確保するために ‘my-process<1>’ という名前が与えられます。このプロセスは、最初のプロセスが終了する前に、バッファ ‘foo’ の末尾にディレクトリ一覧を挿入します。その後、プロセスが終了し、その旨のメッセージがバッファに挿入されます。かなり時間が経過した後、最初のプロセスが終了し、それに関する別のメッセージがバッファに挿入されます。
(start-process "my-process" "foo" "sleep" "100")
⇒ #<process my-process>
(start-process "my-process" "foo" "ls" "-l" "/bin")
⇒ #<process my-process<1>>
---------- Buffer: foo ----------
total 8336
-rwxr-xr-x 1 root root 971384 Mar 30 10:14 bash
-rwxr-xr-x 1 root root 146920 Jul 5 2011 bsd-csh
...
-rwxr-xr-x 1 root root 696880 Feb 28 15:55 zsh4
Process my-process<1> finished
Process my-process finished
---------- Buffer: foo ----------
start-processと同様に、この関数はprogramを実行する新しい非同期サブプロセスを起動し、そのプロセスオブジェクトを返します。
start-processとの違いは、この関数がdefault-directoryの値に基づいてファイル名ハンドラを呼び出す可能性がある点です。このハンドラは、おそらくローカルホスト、あるいはdefault-directoryに対応するリモートホスト上でprogramを実行することになります。後者の場合、default-directoryのローカル部分がプロセスの作業ディレクトリとなります。
この関数は、program や args
の残りの部分に対してファイル名ハンドラを呼び出そうとはしません。そのため、program や args のいずれかが remote-file 構文(特定のファイル名を「マジック」にする を参照)を使用している場合は、file-local-name を通すことで、default-directory
を基準とした相対ファイル名、あるいはリモートホスト上のローカルファイルを特定するファイル名に変換する必要があります。
ファイル名ハンドラの実装によっては、生成されたプロセスオブジェクトに process-filter
や process-sentinel を適用できない場合があります。プロセスフィルタ関数 および センチネル:プロセスステータスの変化の検出 を参照してください。
一部のファイル名ハンドラでは start-file-process
をサポートしていない場合があります(例:ange-ftp-hook-function
関数)。このような場合、この関数は何も行わず、nil を返します。
この関数は start-process と同様ですが、指定した command の実行にシェルを使用する点が異なります。引数 command はシェルコマンド文字列です。変数 shell-file-name で使用するシェルを指定します。
The point of running a program through the shell, rather than directly with
make-process or start-process, is so that you can employ shell features
such as wildcards in the arguments. It follows that if you include any
arbitrary user-specified arguments in the command, you should quote them
with shell-quote-argument first, so that any
special shell characters do not have their special
shell meanings. See Shell
Arguments. Of course, when executing commands based on user input you
should also consider the security implications.
この関数は start-process-shell-command と同様ですが、内部的には
start-file-process を使用しています。このため、default-directory 次第で command
もリモートホスト上で実行可能です。
この変数は、非同期サブプロセスとの通信に使用するデバイスの種類を制御します。値が nil
以外の場合、利用可能な場合は pty が使用されます。それ以外の場合は、パイプが使用されます。
process-connection-type の値は、make-process または start-process
が呼び出された際に有効になります。そのため、これらの関数の呼び出し箇所で変数をバインドすることで、サブプロセスとの通信方法を指定できます。
なお、:stderr パラメータに nil
以外の値を指定して make-process
を呼び出した場合、この変数の値は無視されます。その場合、Emacs はパイプを用いてプロセスと通信します。また、pty
が利用できない場合(MS-Windows)にも無視されます。
(let ((process-connection-type nil)) ; use a pipe
(start-process ...))
特定のサブプロセスが実際にパイプまたはptyを取得したかどうかを判断するには、関数 process-tty-name を使用してください(プロセス情報を参照)。
プロセスセンティネル/フィルタ関数でエラーが発生した場合、Emacsは(デフォルトでは)このエラーを表示した後、process-error-pause-time秒間処理を一時停止し、ユーザーが当該エラーを確認できるようにします。ただし、(こうしたエラーが頻発すると)Emacsが応答しなくなる状況を招く可能性があるため、process-error-pause-timeを0に設定することでこの機能を無効にできます。