For Gauche 0.9.5


Next: , Previous: , Up: ライブラリモジュール - Gauche拡張モジュール   [Contents][Index]

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

Module: gauche.process

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


Next: , Previous: , Up: 高レベルプロセスインタフェース   [Contents][Index]

9.24.1 Running subprocess

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

サブプロセスで、cmd/argsに与えられたコマンドと引数を実行し、 <process>オブジェクトを返します。 <process>オブジェクトについては次節で説明します。

cmd/args引数はリストで、そのcarがコマンド名を、 cdrがコマンドラインに渡す引数を指定します。

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

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

例えば、次の式はls -alを実行します。

(run-process '(ls -al))

上の式をREPLで実行したなら、おそらく戻り値がlsの出力より先に表示されるでしょう。 デフォルトでは、run-processは子プロセスの 終了を待たずに、直ちに戻ります。子プロセスの終了を待ちたい場合はwaitキーワード 引数を使います。

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

あるいは戻り値の<process>オブジェクトを保持しておいて、後で process-waitを呼ぶことによって子プロセスの終了を待つこともできます。 process-waitについてはProcess objectで説明します。

(let1 p (run-process '(ls -al))
  ... do some other work ...
  (process-wait p))

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

(run-process '(ls "-i"))

注:外部プロセスを走らせる方法にはもうひとつ、sys-systemがあります。 こちらはコマンド行を単一の文字列で渡し、シェルを呼び出して解釈させます (プロセス管理参照)。 したがって、入出力のリダイレクトや、パイプでつないだコマンド等もそのまま渡せます。 書き捨てのスクリプトを素早く書くときはそちらの方が便利でしょう。

一方、sys-systemを使う場合には、コマンドの引数を実行時に可変にしたい場合に きちんとエスケープされているかどうかを確認したり (実はgauche.process モジュール中にそれをする関数があります。下のshell-escape-stringを 参照してください)、またsys-systemsystem(3)経由で 呼び出す/bin/shのプラットフォーム間の違いを気にしたりする必要があります。 原則として、sys-systemの使用は固定コマンドを呼び出す簡単な場合に 止めておき、他の仕事にはrun-processを使うのが良いでしょう。

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

子プロセスの実行を細かく制御するために、run-processはたくさんの キーワード引数を取ります。以下でそれらをいくつかのカテゴリに分類して説明します。

同期

run-process argument: wait flag

flag が真の場合、run-process はサブプロセスが終了するまで待ちます。 そうでなければ、サブプロセスは非同期に実行され、run-process は すぐに返ります。これがデフォルトの振る舞いになります。

サブプロセスが非同期に実行している場合、その終了ステータスを回収するために 適切なタイミングで process-wait を呼ぶことは、呼び出し側の責任であることに 注意してください。

;; This returns after wget terminates.
(define p (run-process '(wget http://practical-scheme.net/) :wait #t))

;; Check the exit status
(let1 st (process-exit-status p)
  (cond [(sys-wait-exited? st)
         (print "wget exitted with status " (sys-wait-exit-status st))]
        [(sys-wait-signaled? st)
         (print "wget interrupted by signal " (sys-wait-termsig st))]
        [else
         (print "wget terminated with unknown status " st)]))
run-process argument: fork flag

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

I/Oリダイレクト

run-process argument: redirects (iospec …)

子プロセスのI/Oをどのようにリダイレクトするかを指定します。 各iospecは次の形式のいずれかです。ここでfd, fd0およびfd1子プロセスにおけるファイルディスクリプタを指定する非負の整数です。

(註:簡単にコマンドを走らせて結果を文字列で得たい場合は、 process-output->stringが使えます(Process ports参照)。 また、複数のコマンドをパイプでつなぎたい場合は Running multiple processesを見てください。)

(< fd source)

sourceは文字列、シンボル、キーワード:null、整数、入力ポートのいずれかです。

文字列の場合、それはファイル名を指定します。そのファイルが読み込み用にオープンされ、 子プロセスはfdからその内容を読み込みます。指定されたファイルが存在しないか 読み込み用にオープンできなければエラーが報告されます。

シンボルの場合、一方向のパイプが作られ、その読み出し側の端が子プロセスのfdへと 接続されます。書き込み側の端は (process-input process source) を呼び出すことで入手できます。

:nullの場合、fdはシステムのヌルデバイスからの 読み込みになります。

整数の場合は、現プロセスの読み込み用ファイルディスクリプタを指定します。 そのファイルディスクリプタの読み込み元がdupされて、子プロセスからはfdとして 見えます。

入力ポートの場合は、入力元のファイルディスクリプタがdupされて 子プロセスのfdになります。ファイルディスクリプタを持たないポートを渡した 場合はエラーになります(ポート共通の操作port-file-number参照)。

(<< fd value)
(<<< fd obj)

valueまたはobjを子プロセスの入力ファイルディスクリプタfdへの 入力とします。

<<を使う場合、valueは文字列かユニフォームベクタ (see ユニフォームベクタ)でなければなりません。その内容がそのまま 子プロセスの入力へと送られます。ユニフォームベクタはバイナリデータを渡すのに便利です。

<<<を使う場合、objには任意のSchemeオブジェクトを渡せます。 (write-to-string obj)の結果の文字列が子プロセスの入力へと送られます。

(<& fd0 fd1)

子プロセスのファイルディスクリプタfd0が、 同じく子プロセスのファイルディスクリプタfd1が指しているものと 同じ入力を参照するようにします。 <との違いに注意してください。(< 3 0)とすると、 現プロセスのstdin (ファイルディスクリプタ0) が子プロセスからはファイルディスクリプタ3 として見えるようになります。(<& 3 0)とすると、子プロセスのファイルディスクリプタ3 は子プロセスのstdinと同じものを見るようになります (それは他のiospecによって ファイル等にリダイレクトされているかもしれません)。

<&の処理の順番について、下の方にある註も参照してください。

(> fd sink)
(>> fd sink)

sinkは文字列、シンボル、キーワード:null、整数、あるいは ファイル出力ポートでなければなりません。

文字列の場合、それはファイル名です。指定されたファイルが書き込み用にオープンされ、 子プロセスのファイルディスクリプタfdからそこに書き込むことができます。 指定のファイルが既に存在している場合、>はファイルをまず空にするのに対し、 >>はファイルの後に追加します。 >>>の違いが出るのはsinkがファイルの場合のみです。

sink:nullなら、fdはシステムのヌルデバイスへの 書き出しになります。

整数の場合、それは現プロセスの書き込み用ファイルディスクリプタを 指定します。それがdupされて子プロセスのfdとなります。

出力ポートの場合は、出力先のファイルディスクリプタがdupされて 子プロセスのfdになります。ファイルディスクリプタを持たないポートを渡した 場合はエラーになります(ポート共通の操作port-file-number参照)。

(>& fd0 fd1)

子プロセスのファイルディスクリプタfd0が、子プロセスのファイルディスクリプタfd1 が参照するのと同じ出力先を参照するようにします。 >との違いに注意: (> 2 1)は子プロセスのstderrが現プロセスのstdout と同じところに送られるようにするのに対し、(>& 2 1)は子プロセスのstderr が子プロセスのstdoutに送られます (それは別のiospecによってリダイレクト されているかもしれません)。

;; 子プロセスのstdoutとstderrを一緒にして読み込む
(let1 p (run-process '(command arg)
                     :redirects '((>& 2 1) (> 1 out)))
  (begin0 (port->string (process-output p 'out))
          (process-wait p)))

註: 入力元や出力先にパイプを使う場合、同じ名前(シンボル)を複数の入出力に 指定することはできません。例えば次のコードはエラーとなります。

(run-process '(command) :redirects '((> 1 out) (> 2 out))) ; error!

複数の出力を一つの出力先にマージするには>&を、 一つの入力元を複数の入力で読み込みには<&を使ってください。

(run-process '(command) :redirects '((> 1 out) (>& 2 1)))

同じファイル名を複数の入出力に指定することは、Unixのシェル同様、可能です。 ただしその場合、ファイルはそれぞれの入出力ごとに別々にオープンされる ことに注意してください。例えば同じファイルを複数の出力からオープンして 書き込んだ場合、求める結果が得られないかもしれません(通常のファイルであれば、 一方の出力がもう一方の出力を上書きしてしまうでしょう)。

註: I/Oリダイレクト指定は、unixのシェルと違って、 全て同時に処理されます。つまり、以下の式はどちらも同じように、 stdoutとstderrをファイルoutに書き出す処理となります。

(run-process '(command arg) :redirects '((>& 2 1) (> 1 "out")))
(run-process '(command arg) :redirects '((> 1 "out") (>& 2 1)))

unixのシェルではリダイレクト指定は順に処理されるので、 次の二つのコマンドラインは異なる動作となります。最初の例では 子プロセスのstderrが現時点でのstdout (それは現プロセスのstdoutでもある) へと向けられ、次に子プロセスのstdoutがファイルoutに向けられます。 従ってエラーメッセージは現プロセスのstdoutへと現れます。二番目の例では 最初に子プロセスのstdoutがファイルoutへ向けられるので、 2>&1が処理される時にはstderrの行き先はやはりoutとなります。

$ command arg 2>&1 1>out
$ command arg 1>out 2>&1

run-processredirects引数の順番にかかわらず 常に後者のように動作すると言ってもよいでしょう。

もし前者の例のように子プロセスのstderrだけを親プロセスのstdoutに 向けたいのであれば、次のように>を使うことで実現できます。

(run-process '(command arg) :redirects '((> 2 1) (> 1 "out")))
run-process argument: input source
run-process argument: output sink
run-process argument: error sink

サブプロセスの標準入出力を制御します。 source及びsinkは、文字列、キーワード :pipe、 キーワード:null、整数のファイルディスクリプタ、もしくはシンボルです。

実のところ、これらはredirects引数の略記にすぎません。

:input x   ≡ :redirects '((< 0 x))
:output x  ≡ :redirects '((> 1 x))
:error x   ≡ :redirects '((> 2 x))

キーワード:pipeは互換性のためだけにサポートされています。 それぞれ、シンボルstdinstdoutstderrが 指定されたかのように振る舞います。

:input :pipe   ≡ :redirects '((< 0 stdin))
:output :pipe  ≡ :redirects '((> 1 stdout))
:error :pipe   ≡ :redirects '((> 2 stderr))

すなわち、パイプが作成され、その一方が子プロセスの標準入出力のいずれかに接続されます。 もう一方の端は(process-input process)(process-output process)および (process-error process)によって得ることができます。 (process-input, process-outputname引数が 省略されるとそれぞれstdin, stdoutをデフォルトとし、 また(process-error p)(process-output p 'stderr)と 等価だからです)

引数の意味の詳しい説明については上のredirectsの項を参照してください。

実行環境

run-process argument: directory directory

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

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

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

run-process argument: sigmask mask

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

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

run-process argument: detached flag

真の値が渡されると、作られるプロセスは親プロセスのプロセスグループから 切り離され、独自のプロセスグループを作ります。 デーモンプロセスを作る際に便利です。detached引数の詳しい動作については、 sys-fork-and-exec を見てください (プロセス管理参照)。

run-process argument: host hostspec

この引数は、commandをリモートホストで実行させるのに使います。 hostspecの完全な構文はprotocol:user@hostname:portで、 protocol:user@:portの部分は省略可能です。

protocolはリモートに接続するプロトコルを指定します。現在のところ sshだけがサポートされており、また省略された場合もsshが 使われます。userはリモートでのユーザ名を、hostnameは リモートホスト名を指定します。portprotocolのデフォルト 以外のポートを使いたい場合に指定します。

コマンドライン引数はリモートホスト上で解釈されます。 一方、I/Oリダイレクトはローカル側で処理されす。 例えば、次のコードはリモートマシンの/foo/barの内容を読み、 それをローカルのワーキングディレクトリ内のファイルbazへとコピーします。

(run-process '(cat "bar")
             :host "remote-host.example.com"
             :directory "/foo"
             :output "baz")

Next: , Previous: , Up: 高レベルプロセスインタフェース   [Contents][Index]

9.24.2 Running multiple processes

Function: run-process-pipeline commands :key input output error wait directory sigmask

A convenience routine to run pipeline of processes at once. Example:

(run-process-pipeline '((ls "src/")
                        (grep "\\.c$")
                        (wc -l)))

This is equivalent to shell command pipeline ls src/ | grep '\.c$' | wc -l, i.e. shows the number of C source files in the src subdirectory.

The commands argument is a list of lists. Each list must be cmd/args argument run-process can accept. At least one command must be specified.

The specified commands are run concurrently, with the stdout of the first command is connected to the stdin of the second, and stdout of the second to the stdin of the third, and so on. The stdin of the first command is fed from the source specified by the input keyword argument, and the stdout of the last command is sent to the sink specified by the output keyword argument. The default values of these are the calling process’s stdin and stdout, respectively. See run-process, for the possible values of these arguments.

The stderr of all the processes are sent to the sink specified by the error keyword argument, which is defaulted by the calling process’s stderr.

The wait keyword argument specifies whether run-process-pipeline waits for the completion of the last process. If a true value is given, run-process-pipeline won’t return until the last process exits. If it is #f, run-process-pipeline returns immediately after all the processes are spawned.

The directory and sigmask keyword arguments are applied to all the processes; see run-process for the description of these arguments.

The return value of run-process-pipeline is a list of <process> objects, in the order as given to commands arguments.

Note that the exit status of processes won’t be automatically taken (except for the last one, when wait is true), so the caller must call process-wait on those process objects to clean up the processes.


Next: , Previous: , Up: 高レベルプロセスインタフェース   [Contents][Index]

9.24.3 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: process? obj

(is-a? obj <process>)

Method: process-pid (process <process>)

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

Method: process-command (process <process>)

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

Method: process-input (process <process>) :optional name
Method: process-output (process <process>) :optional name

プロセスの入力もしくは出力に一方の端がつながれたパイプの、もう一方の端を取り出します。 namerun-processredirects引数に与えた 識別用の名前です。次の例を見てください。

(let1 p (run-process '(command arg)
                     :redirects '((< 3 aux-in)
                                  (> 4 aux-out)))
  (let ([auxin  (process-input p 'aux-in)]
        [auxout (process-output p 'aux-out)])
    ;; feed something to the child's input
    (display 'something auxin)
    ;; read data from the child's output
    (read-line auxout)
    …
    )
  (process-wait p))

シンボルaux-inaux-outがパイプを識別するのに 使われています。process-inputが返すのは出力ポートであり、 process-outputが返すのは入力ポートであることに注意してください。

nameが省略された場合、process-inputstdinを、 process-outputstdoutを使います。これらは 子プロセスの標準入力/出力をそれぞれ:input :pipe/:output :pipeで リダイレクトした場合に使われる名前です。

名前に対応するパイプが無い場合は#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"
Method: process-error (process <process>)

これは(process-output process 'stderr)と等価です。

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 を送ります。


Previous: , Up: 高レベルプロセスインタフェース   [Contents][Index]

9.24.4 Process ports

Function: open-input-process-port command :key 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キーワード引数で 変換バッファの大きさを指定することも可能です。文字コード変換の詳細については 文字コード変換を参照して下さい。

(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 :key 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 :key 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 :key 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 :key 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 :key output error encoding conversion-buffer-size on-abnormal-exit

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

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

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

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

Function: process-output->string command :key error encoding conversion-buffer-size on-abnormal-exit
Function: process-output->string-list command :key 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 str :optional flavor

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

省略可能なflavor引数はシンボルを取り、プラットフォームを指定します。 現在はwindowsposixが指定可能です。シェルが エスケープやクオートを処理する方法がこの二つのプラットフォームで大きく 異なるからです。windowsフレーバーの場合はMVCSランタイムの 引数パージングに合わせ、posxiフレーバーの場合はIEEE Std 1003.1に 合わせます。 省略された場合は、プロセスが走っているプラットフォームが デフォルトの値となります。(Cygwinはposixとみなされます。)

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

Function: shell-tokenize-string str :optional flavor

シェルがやるように、文字列strを引数リストに分割します。

(shell-tokenize-string "grep -n -e \"foo bar\" log")
 ⇒ ("grep" "-n" "-e" "foo bar" "log")

省略可能なflavor引数はシンボルwindowsposixを取り、 構文を指定します。windowsの場合はMVCSランタイムの 引数パージングに合わせ、posxiフレーバーの場合はIEEE Std 1003.1 Shell Command Languageに合わせます。 省略された場合は、プロセスが走っているプラットフォームが デフォルトの値となります。(Cygwinはposixとみなされます。)

この手続きはシェルの変数置換のような高度な機能は持っていません。 もしそういった解釈が必要なメタ文字に出会った場合はエラーが投げられます。 言い換えれば、メタ文字はstrの中で全て適切にクオートされている 必要があります。

(shell-tokenize-string "echo $foo" 'posix)
  ⇒ signals error

(shell-tokenize-string "echo \"$foo\"" 'posix)
  ⇒ still signals error

(shell-tokenize-string "echo '$foo'" 'posix)
  ⇒ ("echo" "$foo")

(shell-tokenize-string "echo \\$foo" 'posix)
  ⇒ ("echo" "$foo")

Previous: , Up: 高レベルプロセスインタフェース   [Contents][Index]