[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.16 gauche.process - 高レベルプロセスインタフェース

Module: gauche.process

このモジュールは、sys-forksys-exec などの低レベルな システムコールの上に実装された、Unix プロセス制御の高レベル API を提供します。 また、このモジュールは、サブプロセスに情報を送ったり、サブプロセスから 情報を受け取ったりするのに便利な「プロセスポート」を提供します。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.16.1 Process object

Class: <process>

子プロセスの状態を保持するためのオブジェクト。以下で説明される run-process 手続きにより、プロセスを作ることができます。 次章で説明するプロセスポートもプロセスオブジェクトを用いています。

<process>クラスは、run-processopen-input-process といった高レベルAPIで作られた子プロセスの状態を管理しています。 それらの子プロセスの終了ステータスをとるには、 process-waitprocess-wait-anyといった 高レベルAPIを利用してください。これらの手続きはシステムコール以外の情報管理も 行います。sys-waitsys-waitpidといった低レベルAPIで 直接子プロセスの終了ステータスを取ると、<process>クラスの 内部状態に矛盾が生じます。

Class: <process-abnormal-exit>

主にプロセスポートユーティリティ関数で使われるコンディション型。 <error>を継承。このコンディション型は高レベルプロセスポートユーティ リティが子プロセスが非ゼロのexitステータスで終了したことを検知したとき に投げられます。

Instance Variable of <process-abnormal-exit>: process

プロセスオブジェクト。

注: Unix用語では,exitステータスにかかわらず,プロセスがcalling exit(2)を呼ぶか,main()から帰った場合を「正常な終了」と しています。コマンドによっては非ゼロのexitステータスで何らかの正常な実行結果を 示すものもあります(grep(1)など)。しかし,ほとんどのコマ ンドでは,非ゼロの exit ステータスは要求された操作が実行できなかったこ とを表わします。それゆえ上のような場合を例外的な場合として扱います。

Function: run-process cmd/args &keyword input output error   fork wait directory host sigmask

サブプロセスで、cmd/argsに与えられたコマンドと引数を実行し、 <process>オブジェクトを返します。 cmd/args引数はリストで、そのcarがコマンド名を、 cdrがコマンドラインに渡す引数を指定します。

コマンド名がスラッシュを含んでいた場合、それは実行可能ファイルへの パス名と解釈されます。そうでなければ、コマンド名がPATH環境変数 にあるディレクトリから探されます。

cmd/argsの各要素は、便利なようにx->stringで文字列に 変換されます。

以下のキーワード引数が認識されます。

:input file
:output file
:error file

これらの引数は、サブプロセスの標準入出力を制御します。 file は文字列かキーワード :pipe です。 文字列の場合は、プロセスの標準入力、標準出力、標準エラーはそのファイルに なります。:pipe の場合は、プロセスの対応する標準入出力はパイプに 結び付けられ、そのパイプのもう一方はプロセスの呼び出し側で利用できます。

:wait flag

flag が真の場合、run-process はサブプロセスが終了するまで待ちます。 そうでなければ、サブプロセスは非同期に実行され、run-process は すぐに返ります。これがデフォルトの振る舞いになります。 サブプロセスが非同期に実行している場合、その終了ステータスを回収するために 適切なタイミングで process-wait を呼ぶことは、呼び出し側の責任であることに 注意してください。

:fork flag

flag が真の場合、run-process はサブプロセスを実行するために フォークします。これはデフォルトの振る舞いです。flag が偽の場合、 run-process は直接 sys-exec を呼ぶので、それは返りません。

:host hostspec

この引数は、commandをリモートホストで実行させるのに使います。 hostspecの完全な構文はprotocol:user@hostname:portで、 protocol:user@:portの部分は省略可能です。 protocolはリモートに接続するプロトコルを指定します。現在のところ sshだけがサポートされており、また省略された場合もsshが 使われます。userはリモートでのユーザ名を、hostnameは リモートホスト名を指定します。portprotocolのデフォルト 以外のポートを使いたい場合に指定します。

:directory directory

directoryに文字列が与えられた場合、 そのディレクトリが起動されるプロセスのワーキングディレクトリとなります。 #fが与えられた場合はの引数は何もしません。 文字列か#f以外が与えられた場合、もしくは文字列が存在するディレクトリの 名前でない場合はエラーが報告されます。

hostキーワード引数も与えられている場合、この引数は リモートプロセスのワーキングディレクトリを指定します。

註: run-processdirectoryが有効な値であることを事前に チェックしますが、実際のchdir(2)exec(2)の直前に 行われます。事前のチェックにもかかわらずchdirが失敗する可能性が あります。その時点ではrun-processの呼び出し元にエラーを伝える 確実な方法が無いため、Gaucheは標準エラー出力にメッセージを印字して exitします。頑健なプログラムを書く場合、そのようなケースにも留意して下さい。

:sigmask mask

mask<sys-sigset>のインスタンス、整数のリスト、 あるいは#fでなければなりません。 <sys-sigset>のインスタンスである場合、それが実行する プロセスのシグナルマスクになります。整数のリストの場合は各整数が マスクすべきシグナル番号とみなされます。マルチスレッドアプリケーションで run-processを使う場合はシグナルマスクを適切に設定することが重要です。 sys-execの説明を参照して下さい (プロセス管理)。

hostキーワード引数が与えられている場合は、この引数は ローカル側のプロセス(ssh)のみのシグナルマスクをセットします。

次の例はls -alを同期的に実行します。

 
(run-process '(ls -al) :wait #t)

ところで、-iは虚数として読まれることに注意してください。 -iを引数として渡したい場合は文字列にするか、|-i|のように エスケープしてシンボルにする必要があります。

 
(run-process '(ls "-i") :wait #t)

注:以前のバージョンのこの手続きは引数の取りかたが若干異なっており、 例えば(run-process "ls" "-al" :wait #t)のように呼び出しました。 これはSTkとの互換性によるものです。現在でもこの呼び出しはサポートされていますが、 非推奨です。

Function: process? obj

(is-a? obj <process>)

Method: process-pid (process <process>)

サブプロセス process のプロセスIDを返します。

Method: process-command (process <process>)

サブプロセス process 内で起動されたコマンドを返します。

Method: process-input (process <process>)
Method: process-output (process <process>)
Method: process-error (process <process>)

プロセスの標準入力、標準出力、標準エラーがパイプに接続されている場合は、 パイプのもう一方の終端を返します。例えば、process-input は、 process の標準入力へデータを送ることができる出力ポートを返します。 process-outputprocess の標準出力からデータを読み込むことの できる入力ポートを返します。そして、process-error は、process の標準エラーからデータを読み込むことのできる入力ポートを返します。 対応する入出力がパイプに接続されていない場合、手続きは #f を返します。

 
(let* ((process (run-process '("date") :output :pipe))
       (line (read-line (process-output process))))
  (process-wait process)
  line)
 ⇒ "Fri Jun 22 22:22:22 HST 2001"
Function: process-alive? process

process が生きている場合は真を返します。process-wait によって 明示的にチェックされない限り、Gauche はサブプロセスのステータスを知ることが できないことに注意してください。

Function: process-list

アクティブなプロセスのリストを返します。プロセスは、その終了ステータスが process-wait によって明示的に回収されない場合は、アクティブなまま 残ります。 ひとたび終了ステータスが回収され、プロセスの状態がインアクティブに 変更されると、そのプロセスはprocess-listが返すリストからは除かれます。

Function: process-wait process &optional nohang error-on-nonzero-status

サブプロセス process の終了ステータスを取得し、process のstatusスロットに値を格納します。statusスロットの値は process-exit-statusで得ることができます。

デフォルトでは、この手続きはprocess が終了するまで実行を一時停止します。 しかし、nohangに真の値が与えられた場合は、processが終了して いない場合にも直ちに返ります。

オプショナル引数error-on-nonzero-statusに真の値が与えられた場合、 この手続きは得られた終了ステータスが0で無い場合に <process-abnormal-exit>エラーを投げます。

この呼び出しによってprocessの終了ステータスが実際に取得された場合は #tを、そうでなければ#fを返します。

Function: process-wait-any &optional nohang

run-processで作られたサブプロセスのどれかの終了ステータスを取得します。 終了ステータスが取得できたプロセスのプロセスオブジェクトを返します。

真の値がnohangに与えられた場合は、どの子プロセスも終了していない場合は 直ちに#fを返します。そうでなければ、この手続きはいずれかの子プロセスが 終了するまで待ちます。

子プロセスが存在しない場合は、この手続きは直ちに#fを返します。

Function: process-exit-status process

process-waitによって取得されたprocessの終了ステータスを 返します。processに対してprocess-waitを呼ぶ前にこの手続きを 呼んだ場合の結果は未定義です。

終了ステータスの解釈はプラットフォームに依存します。プロセスが自発的に (exitを呼んで)終了したか、それともシグナルによって終了させられたかを 確かめるにはsys-wait-exited?sys-wait-signaled?を 使ってください。また、終了コードもしくは終了と原因となったシグナルを 知るにはsys-wait-exit-statussys-wait-termsig 使ってください (プロセス管理参照)。

Function: process-send-signal process signal

サブプロセス process にシグナル signal を送ります。 signal は正確整数のシグナルナンバーでなければなりません。 シグナルの定義済み変数については、シグナルを参照して下さい。

Function: process-kill process
Function: process-stop process
Function: process-continue process

それぞれ、process に、SIGKILL、SIGSTOP、SIGCONT を送ります。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.16.2 Process ports

Function: open-input-process-port command &keyword input error encoding conversion-buffer-size

command を子プロセスで非同期に実行します。 走らせた子プロセスの標準出力につながれた入力ポートと、 プロセスオブジェクトの二つの値を返します。

commandは文字列かリストです。

文字列の場合、それは/bin/shに渡されます。 環境変数の置換やグロブパターン、リダイレクトなどのシェルの機能が 文字列中で使えます。 文字列をつなぎ合わせてコマンドラインを作成する場合、 特殊文字をシェルに解釈してほしくなければ、それを正しくエスケープするのは 呼び出し元の責任です。下で説明するshell-escape-stringは 助けになるかもしれません。

commandがリストの場合は、各要素がx->stringで文字列に 変換された後に、sys-execを使って直接コマンドを起動します (リストのcarがコマンドのパス名とargv[0]の両方に使われます)。 シェルの介入を避けたい場合はこの形式を使うと良いでしょう。 特殊文字をエスケープする必要はありません。

デフォルトでは、子プロセスの標準入力は/dev/nullにリダイレクトされ、 標準エラー出力は呼び出したプロセスと共有されます。 inputerrorキーワード引数にパス名を与えることで、 これらの出力をリダイレクトすることができます。

また、プロセスの出力の文字エンコーディングを指定するために encodingキーワード引数を与えることもできます。 それがGaucheの内部エンコーディングと異なっていた場合、 open-input-process-portは文字コード変換ポートを挿入します。 encodingが与えられた場合、conversion-buffer-sizeキーワード引数で 変換バッファの大きさを指定することも可能です。文字コード変換の詳細については gauche.charconv - 文字コード変換を参照して下さい。

 
(receive (port process) (open-input-process-port "ls -l Makefile")
  (begin0 (read-line port)
          (process-wait process)))
 ⇒ "-rw-r--r--   1 shiro    users        1013 Jun 22 21:09 Makefile"

(receive (port process) (open-input-process-port '(ls -l "Makefile"))
  (begin0 (read-line port)
          (process-wait process)))
 ⇒ "-rw-r--r--   1 shiro    users        1013 Jun 22 21:09 Makefile"

(open-input-process-port "command 2>&1")
 ⇒ ;the port reads both stdout and stderr

(open-input-process-port "command 2>&1 1>/dev/null")
 ⇒ ;the port reads stderr

サブプロセスの終了ステータスは自動的に回収されません。 process-wait を呼ぶことは呼び出し側の責任であり、これを怠ると サブプロセスはゾンビプロセスになります。それが面倒であれば、以下の 手続きを使うことができます。

Function: call-with-input-process command proc &keyword input error encoding conversion-buffer-size on-abnormal-exit

子プロセスでcommand を実行し、その標準出力と入力ポートを パイプで繋ぎ、そのポートを引数として proc を呼び出します。 proc が返るとその終了ステータスを回収し、proc が返した 結果を返します。proc がエラーを通知しても、クリーンアップは 行われます。

キーワード引数on-abnormal-exitは子プロセスが0以外の終了ステータス を返した場合の振舞いを指定します。その値は:error(デフォルト)、 :ignore、もしくは一引数の手続きでなければなりません。 値が:errorの場合、0以外の終了ステータスは <process-abnormal-exit>エラーコンディションを発生させます。 コンディションオブジェクトのprocessスロットには子プロセスオブジェクトが 保持されます。値が:ignoreの場合、0以外の終了ステータスに対して 特別なアクションは取られません。値が手続きの場合、0以外の終了ステータスに対して 子プロセスオブジェクトを引数にしてその手続きが呼ばれます。その手続きが 戻れば、call-with-input-processは正常動作と同じように戻ります。

commandおよび他のキーワード引数の意味はopen-input-process-portと 同じです。

 
(call-with-input-process "ls -l *"
  (lambda (p) (read-line p)))
Function: with-input-from-process command thunk &keyword input error encoding conversion-buffer-size on-abnormal-exit

子プロセスで command を実行し、コマンドの標準出力に 接続された現在の入力ポートとともに thunk を呼び出します。 thunkが終了するかエラーを投げた後に、コマンドの終了ステータスが 回収されます。

commandおよびキーワード引数の意味はcall-with-input-processと 同じです。

 
(with-input-from-process "ls -l *" read-line)
Function: open-output-process-port command &keyword output error encoding conversion-buffer-size

子プロセスで command を非同期に実行します。 子プロセスの標準入力に接続された出力ポートと、 プロセスオブジェクトの二つの値を返します。

command引数、およびencodingconversion-buffer-sizeの 意味は、open-input-process-portと同じです。

デフォルトでは、子プロセスの標準出力は/dev/nullにリダイレクトされ、 標準エラー出力は呼び出したプロセスと共有されます。 outputerrorキーワード引数にパス名を与えることで、 これらの出力をリダイレクトすることができます。

サブプロセスの終了ステータスは自動的には回収されません。 適切なタイミングで、サブプロセスに対して process-wait を呼ぶ 必要があります。

Function: call-with-output-process command proc &keyword output error encoding conversion-buffer-size on-abnormal-exit

command を子プロセスで実行し、コマンドの標準入力に 接続された出力ポートとともに proc を呼び出します。 コマンドの終了ステータスは、proc が返るかエラーを通知した 後に回収されます。

キーワード引数の意味はopen-output-process-portと同じです。 ただしon-abnormal-exitについてはcall-with-input-process で説明したのと同じ意味です。

 
(call-with-output-process "/usr/sbin/sendmail"
  (lambda (out) (display mail-body out)))
Function: with-output-to-process command thunk &keyword output error encoding conversion-buffer-size on-abnormal-exit

コマンドの標準入力に接続された出力ポートが、thunk の実行中は 現在の出力ポートにセットされることを除いて、call-with-output-process と同じです。

Function: call-with-process-io command proc &keyword error encoding conversion-buffer-size on-abnormal-exit

command をサブプロセスで実行し、proc を2つの引数と ともに呼び出します。最初の引数は入力ポートで、コマンドの標準出力に 接続されたものです。2番目の引数は出力ポートでコマンドの標準入力に 接続されたものです。コマンドからのエラー出力は、errorキーワード 引数でパス名が指定されない限り、呼び出したプロセスのエラー出力が共有されます。

コマンドの終了ステータスは、procが戻るかエラーを投げた場合に 回収されます。

Function: process-output->string command &keyword error encoding conversion-buffer-size on-abnormal-exit
Function: process-output->string-list command &keyword error encoding conversion-buffer-size on-abnormal-exit

command を実行し、その(標準出力への)出力を回収して返します。 process-output->stringcommand からの全ての出力を連結し 1つの文字列とします。その際、空白文字からなるシーケンスは1つの空白に 置換されます。このアクションは、シェルスクリプトにおける「コマンド置換」 に似たものです。 process-output->string-listcommand からの出力を行ごとに 回収し、それらをリストにしたものを返します。改行文字は削除されます。

内部的には、commandcall-with-input-process により 実行されます。キーワード引数はcall-with-input-processに そのまま渡されます。

 
(process-output->string '(uname -smp))
  ⇒ "Linux i686 unknown"

(process-output->string '(ls))
  ⇒ "a.out foo.c foo.c~ foo.o"

(process-output->string-list '(ls))
  ⇒ ("a.out" "foo.c" "foo.c~" "foo.o")
Function: shell-escape-string arg

argがシェルのコマンドライン引数解析に影響を与える文字を含んでいる場合、 それらがシェルによって解釈されないようにエスケープされた文字列を返します。 そうでなければarg自体を返します。

自分でコマンドライン文字列を組み立てる必要がある場合に使ってください。 (単一のコマンドライン文字列でなく、コマンドライン引数のリストを渡す場合は エスケープの必要はありません。引数はシェルを通さずに子プロセスに渡される からです。)

Windowsネイティブビルドの場合、この手続きはWindowsの標準Cランタイムの 引数解析に合わせてあります。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated by Shiro Kawai on November, 22 2009 using texi2html 1.78.