メインコンテンツまでスキップ

ソケット、プロセス、およびストリーム入出力

SenseTalkは、ソケット、プロセス、および標準入出力ストリーム(つまり、stdin、stdout、stderr)の読み書きのための一連のコマンドを提供します。基本的に、これらの形式はすべてデータストリームとして扱うことができます。 readおよびwriteコマンドには、多くの形式の数字、テキスト、および生のバイナリデータを含む任意のタイプのデータを簡単に読み書きするための多くのオプションが含まれています。 HTTPとXML-RPCメッセージも直接サポートされており、インターネット上の多くのサーバーとの通信をさらに簡単にします。

ストリームの種類によって詳細が異なる場合がありますが、それらすべてを利用する基本的なプロセスは同じシーケンスに従います: openreadおよび/またはwriteclose。 このシーケンスの主な例外は、標準入力、標準出力、および標準エラーストリームは常に開いていると見なされるため、開くまたは閉じる必要がないことです。

ノート

ソケット、プロセス、ストリームデータを操作するために使用するコマンドと関数は、ファイルやファイルシステムオブジェクトを操作するために使用できるコマンドと関数に似ています。 ファイルおよびファイルシステムの操作についての情報については、File and Folder Interactionを参照してください。

ソケット入出力コマンド(open socketclose socketread from socket、およびwrite … to socket)を使用すると、別のプロセスが提供するソケットへの接続を開き、その接続を通じてデータを読み書きすることができます。 ソケットは単なる2つのプロセス間の開いた通信チャネルであるため、特定の位置にシークすることはできません。

同様に、プロセス入出力コマンド(open processclose processread from process、およびwrite … to process)を使用すると、外部プロセスを起動し、そのプロセスの標準入力に書き込み、標準出力から読み取ることにより通信することができます。

readおよびwriteコマンドはまた、標準入力から読み取り、標準出力または標準エラーストリームに書き込むためにも使用できます(read from inputwrite … to outputwrite … to error)。

openSockets関数は、現在開いているすべてのソケットのリストを返します。

The DefaultStringEncodingグローバルプロパティは、ファイルまたはソケットからテキストを読み取るか書き込むときに使用されるエンコーディング形式を制御します。

Open Socketコマンド

動作: open socketコマンドは、ソケットから何かを読み取るか、そのソケットにreadまたはwriteコマンドを使用して何かを書き込む前に使用する必要があります。ソケットの使用が終了したら、close socketコマンドを使用して閉じる必要があります。

Open socketは、別のプロセス(プログラム)へのTCPソケット接続を確立します。その他のプロセスは、同じコンピューター上で実行されているか、またはネットワーク上の他のコンピューター上で実行されている可能性があります。それはすでに実行されており、SenseTalkが接続できるソケットを登録している必要があります。接続が確立されると、データは両方の側が理解する方法でどちらの方向にも送信される可能性があります。

構文:
open socket socketIdentifier

_socketIdentifier_は、_host:port_の形式でなければなりません。ここで、_host_はマシンの名前またはIPアドレスであり、_port_は接続するソケットのそのマシンのポート番号です。

_socketIdentifier_は、任意の数値または識別子文字列に続くポンド記号#(または垂直バー|)文字で終わる場合があります。これは、同じホストとポートに対して複数の接続を確立し、各接続を一意に識別するための識別子を複数作成することを可能にします - 正しい接続を識別するためにreadwrite、およびcloseコマンドで適切な_socketIdentifier_を使用するだけです。

ソケット接続がthe readTimeoutグローバルプロパティで指定された時間内に確立できない場合、例外がスローされます。現在開いているすべてのソケットのリストを取得するためにopenSockets関数を使用します。

例:

open socket remoteListener

例:

open socket "192.168.1.4:22"

例:

open socket "localhost:5900#2"

Open Processコマンド

動作: 外部プロセスを起動し、スクリプトがその他のプロセスと対話できる接続を開きます。必要なのは外部プロセスを実行し、そのプロセスが完了したときにそのプロセスからの出力を受け取ることだけであれば、shell関数はそれを達成するためのはるかに簡単な方法を提供します。一方、オープンプロセスメカニズムは、スクリプトが他のプロセスと複雑な対話を行うことを可能にし、またはスクリプトをブロックせずに長時間の操作を開始し、その操作の結果をスクリプトの後の時点で取得することを可能にする、はるかに大きな柔軟性を提供します。

Open processは、他のプログラムを実行するためのシェルである可能性が最も高い(そして最も一般的な)別のプロセス(プログラム)を起動します。他のプロセスが起動されると、接続が確立され、テキストはどちらの方向にも送信できます - スクリプトは他のプロセスの標準入力に書き込み、そのプロセスの標準出力から読み取ることができます。

プロセスが起動できない場合、result関数は例外に設定されます(The ThrowExceptionResultsグローバルプロパティがtrueに設定されている場合、例外がスローされます)。現在開いているすべてのプロセスのリストを取得するためにopenProcesses関数を使用できます。

構文:
open process processIdentifier {with {options} options}

_processIdentifier_は_processPath#identifier_の形であるべきです。ここで_processPath_は実行するプロセスのフルパスです。_processPath_が省略された場合、シェルプロセスが起動されます(the shellCommandグローバルプロパティによって指定されます)。#_identifier_部分もオプションです - これは_processIdentifier_を一意にする方法として機能し、スクリプトが同じ_processPath_を使用する複数のプロセスを同時に開いて対話することができます。

_options_が使用される場合、それはこれらのプロパティを含む可能性があるプロパティリストであるべきです:

parametersプロセスが起動されたときにそのプロセスにパラメータとして渡される値のリスト
folderまたはdirectoryプロセスが実行される現在のディレクトリ
environment環境変数とその値を指定するプロパティリスト

例:

open process preferredShell & "#myshell"

例:

open process "/bin/sh" with options myOptions

例:

open process "/usr/local/bin/mysql#2"

Close Socket, Close Process, Close Allコマンド

動作: ソケットを閉じる、またはプロセスを閉じる、またはすべての開いているファイル、ソケット、またはプロセスを閉じる。 close all socketsコマンドは現在開いているすべてのソケットを閉じます、どのスクリプトまたはハンドラがソケットを開いたかに関係なく。この動作は他のスクリプトがソケットを開いており、まだ使用中の場合に問題を引き起こす可能性があります。 openSockets()関数を使用して開いているすべてのソケットのリストを取得します。同じことがclose all processesコマンドにも当てはまります。

close socketコマンドは、以前open socketコマンドで開いたソケットを閉じます。 socketIdentifierはソケットを開くときに使用した識別子と同一でなければなりません。

close processコマンドは、以前open processコマンドで開いたプロセスを閉じます。 processIdentifierはプロセスを開くときに使用した識別子と同一でなければなりません。

close all socketsおよびclose all processesコマンドは現在開いているすべてのソケットまたはプロセスを閉じるために使用できます。SenseTalkはスクリプトの実行が停止するたびに自動的にすべての開いているソケットとプロセスを閉じますが、スクリプトがそれらの操作を終えたときにそれらを閉じることは良い習慣です。

構文:
close socket socketIdentifier
close process processIdentifier
close all sockets
close all processes

例:

close all processes -- open all processesを閉じる

例:

close socket "localhost:5900"

例:

close process "#9"

Read from Socket, Read from Process, Read from Inputコマンド

動作: 開いているソケットまたは開いているプロセス、または標準入力ストリームからデータ(テキストまたは数字)を読み取ります。

read from ...コマンドを使用してソケット、プロセス、または標準入力からデータを読み取ります。データは変数itまたは指定された目的のコンテナ(into句を使用して)に読み込まれます。これ以上読み取るデータがない場合、目的のコンテナは空になります。要求された量より少ないデータが読み取られると、result関数は理由(たとえばtime out)を示す値を含むようになります。

readコマンドは、指定された数の文字、単語、アイテム、行、またはバイトを読み取ることができます。指定された区切り文字が見つかるまで読み取ることもできます。または、いくつかの異なるタイプの数値値のリストを読み取ることもできます。読み取りは現在の位置から始まります。readコマンドの構文は柔軟で、さまざまなオプションを任意の便利な順序で指定できます。

ノート

ファイルから読み取るには、Read from File Commandを参照してください。

構文:
read Options

Source Options: 必須.

from socket socketIdentifier
from process processIdentifier
from [input | stdin]

Quantity Options: オプション。一度に一つだけ使用できます.

until [{the} eof | {the} end {of {the} file} | terminator]
for quantity {dataType}
[a | an | quantity] dataType
{for} {a | an} http {message | request | response} {for} {a | an} [xmlrpc | xml-rpc] {message | request | response}

その他のオプション: オプション。一度に複数使用できます。

at startPos
[ in | [timeout | time out] {after | in} ] timeoutDuration
into container

三つのfromオプションの一つは必須で、読み取り元を指定する必要があります。他のすべてのオプションはオプションですが、各タイプは一つだけ指定可能です。forオプションもuntilオプションも指定されていない場合、単一バイトが読み取られます。into _container_が指定されていない場合、値は特別なit変数.に読み取られます。

テクニカルトーク

標準入力ストリームを開く必要はありません - それは常に開いています(あなたが好むならば、stdinとしてinputの代わりに参照することができます)。

ソケットから読み取る場合、_socketIdentifier_表現は、以前にopen socketコマンドでソケットが開かれたときに使用された正確な識別子を生成する必要があります。

プロセスから読み取る場合、_processIdentifier_表現は、以前にopen processコマンドでプロセスが開かれたときに使用された正確な識別子を生成する必要があります。読み取られる値は、プロセスからの標準出力に対応します。

into _container_が指定された場合、読み取られたデータは指定されたコンテナに入れられます。intoオプションが指定されていない場合、データは特別なit変数に読み取られます。

until _terminator_が指定されている場合、指定された文字または文字列の次の出現までのすべての文字が読み取られます。これは、ソースから一行ずつ読み取るのに便利です(終端文字としてreturnを使用することで)、または他の区切り文字(tabなど)まで読み取ります。_terminator_は長さが一文字以上の場合もあり、読み取った値の一部として返されます。until eofまたはuntil endを指定すると、ファイルの終わりまで、またはソケットまたはストリームからの入力の終わりまで読み取ります。標準入力ストリームは、Control-D文字が受信された後に終わりに達したことを示します。ソケットとプロセスの場合、until eofまたはuntil endオプションは、入力が利用可能になるか、またはthe readTimeoutまたはin _timeLimit_の期間が経過するまで待ちます(後述)。これにより、入力が予期されるときの読み取りが大幅に簡素化されます。

for _quantity dataType_が使用される場合、_quantity_に指定された文字数または他のデータ要素がファイルから読み取られます。_dataType_がテキストチャンクタイプ(characterswordsitems、またはlines)の場合、要求された量が利用可能になるまでテキストが読み取られます。最後の区切り文字(ある場合)は、読み取られたテキストには含まれません。_dataType_が指定されていない場合、バイトが仮定されます(この場合、forが必要です)。

in _timeoutDuration_オプションは、readコマンドが要求されたデータを利用可能にするのを待つ最大時間を提供します。時間が指定されていない場合、the readTimeoutのグローバルプロパティの値が代わりに使用されます。要求されたデータがtimeLimitまたはreadTimeoutで指定された時間内に読み取られない場合、読み取られたものは返され、the result関数は_time out_を示すように設定されます。

テキストチャンクタイプの代わりに数値_dataType_を指定すると、読み取りによってitまたは_container_に格納される値は、読み取られたデータ値のリストになります。以下の数値データタイプを使用することができます。

DataTypeValue
int1または8-bit integer
uint1またはunsigned 8-bit integer
int2または16-bit integerまたはshort integer
uint2またはunsigned 16-bit integer
int4または32-bit integerまたはinteger
uint4またはunsigned 32-bit integer
int8または64-bit integer
uint8またはunsigned 64-bit integer
real4または32-bit realまたはfloat
real8または64-bit realまたはdouble

例:

read from input until return-- ユーザーが入力したテキストを読む

例:

read from process mysql until end -- 利用可能なテキストを読む

例:

read into numList from socket inStream for3 unsigned integers

例:

read 6 unsigned 8-bit integers from socket rfb into unitSales

例:

read 10 chars from socket "192.168.1.4:22" in 15 seconds

HTTPメッセージの送受信

ソケットがHTTPプロトコルを使用して通信に使用される場合、SenseTalkはHTTPメッセージの直接読み書きをサポートします。メッセージを読むには、これらのコマンド(またはその変形)のいずれかを使用します:

read an HTTP message from socket clientSock
read from socket myHTTP for an HTTP request
read an HTTP response into theReply from socket remoteService

読み取った値は、読み取られたHTTPメッセージに含まれるすべての情報を持つプロパティリストになります。これには、Method、Path、Headerプロパティなどが含まれ、以下のような形になります:

{Header:{Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8”, "Accept-Encoding”:"gzip, deflate”, "Accept-Language”:"en-us”, Connection:"keep-alive”, Host:"localhost:5991”, "User-Agent”:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22”}, HTTPMessageType:"Request”, Method:"GET”, Path:"/”, Version:"HTTP/1.1”}

同様に、HTTPメッセージはwriteコマンドを使用してソケットを通じて送信することができます。プロパティリストからHTTPメッセージを書き込むには、HTTPMessage()関数またはas http演算子を使用してプロパティリストをHTTPメッセージに変換し、writeコマンドを使用してそれをソケットに書き込みます:

write HTTPMessage(status:200, body:htmlContents) to socket webClient
write replyMsg as http to socket customerSocket

送信するHTTPメッセージは、以下のプロパティを含むことができるプロパティリストの形式である必要があります:

HTTPリクエストメッセージ

  • Method: GETまたはPOST(省略された場合、Bodyが提供されていない場合はGETが、Bodyが提供されている場合はPOSTが想定されます);
  • Request: サーバ上で要求されているリソースへのパス(必須);
  • Version: 提供されていない場合、HTTP/1.1が想定されます;
  • Header: 与えられた場合、ヘッダーキーと値のプロパティリストでなければなりません;
  • Body: メッセージの本文。本文はテキストであるか、またはプロパティリストである可能性があり、その場合は自動的にキー/値のペアでエンコードされます。

HTTPレスポンスメッセージ

  • Version: 提供されていない場合、HTTP/1.1が想定されます;
  • Status: 送信する数値ステータス値。指定されていない場合、デフォルトは200です;
  • Reason: 返されたステータスの理由のテキスト。デフォルトはOKです;
  • Body: 送信される内容。ウェブサーバーの場合、通常はページのHTMLコードです。ボディはプロパティリストである可能性があり、その場合は自動的にキー/値のペアでエンコードされます。

関連項目:

Write to Sockets, Write to Process, Write to Output, Write to Error コマンド

動作: データをソケットやプロセスに書き込む、または標準出力や標準エラーストリームに書き込む。_Data_は有効なSenseTalk表現であれば何でも可能です。_dataType_が指定されていない場合、_data_表現の値は文字列として扱われ、指定されたソケットやストリームに書き出されます。

_socketIdentifier_表現は、open socketコマンドで以前に開かれたソケットの識別子を生成しなければなりません。

_processIdentifier_表現は、open processコマンドで以前に開かれたプロセスの識別子を生成しなければなりません。書き込まれたデータは、プロセスの標準入力に送信されます。

as _dataType_が指定されている場合、データは書き込み前にそのバイナリ形式に変換されます。この場合、_data_は数値のリストであり、すべて同じデータタイプに変換されます。有効なデータタイプのリストについては、readコマンドを参照してください。

構文:
write data {as dataType} to socket socketIdentifier
write data {as dataType} to process processIdentifier
write data {as dataType} to [output | stdout | error | stderr]

例:

write "ls -l" & return to process "#4"

例:

write "Pleaseenter your account id: " to output

例:

write [2,3,5,9] as 8-bit integers to socket msock

OpenSockets 関数

動作: open socket コマンドの結果として現在開いている全てのソケットのリストを返します。

構文:
openSockets()
the openSockets

例:

repeat with each item of the openSockets
if it begins with "192.168.1.12:" then close socket it
end repeat

OpenProcesses 関数

動作: open process コマンドの結果として現在開いている、そして対話可能な全てのプロセスのリストを返します。

構文:
openProcesses()
the openProcesses

例:

repeat with each item of the openProcesses
if it begins with "/usr/bin/ssh" then
write "logout" & return to process it
end if
end repeat

SenseTalkでXML-RPCメッセージの送受信

XML-RPCリクエストを送信するために、post xmlrpc コマンドが使われます:

set myRequest to {methodName:"system.listMethods"}
post xmlrpc myRequest to url serverURL

投稿されるメッセージは、MethodName プロパティを持つプロパティリストでなければならず、オプションでParamsとHeaderプロパティを持つこともできます:

  • MethodName: 必須。呼び出されるメソッド名;
  • Params: パラメータ値の配列。呼び出されるメソッドのタイプに合わせて個々の値が正しくエンコードされるように、必要に応じて "as boolean", "as text", "as date"などを指定します;
  • Header: オプション。他のヘッダー要素のプロパティリスト;
  • User-Agent: Header プロパティで指定されていない場合、SenseTalkの長いバージョンが供給されます。

post コマンドで与えられたURLは、サーバ上の特定のサービスを識別するためのパスを含むことができます。サーバからの応答は、変数 it に保存されます。

XML-RPCの応答を送信するには、XMLRPCResponse() 関数または XMLRPCFault() 関数と、write コマンドを使用します:

write XMLRPCResponse(responseData) to socket rpcClient
write XMLRPCFault(33, "bad mojo") to socket rpcClient

XMLRPCResponse() 関数

少なくとも二つのパラメータが必要です:整数のフォールトコード、およびフォールト文字列。第三のオプションのパラメータが含まれている場合、それはメッセージに含める追加のHTTPヘッダを含むプロパティリストでなければなりません。

XMLRPCFault() 関数

一つまたは二つのパラメータを取ります。最初のパラメータは応答で返される値であり、必須です。それはリストまたはプロパティリストを含む任意のタイプの値であることができます。二つ目のパラメータはオプションです。提供される場合、それはメッセージに含める追加のHTTPヘッダを含むプロパティリストでなければなりません。

ソケットでXML-RPCメッセージを受信するためには、readコマンドを使用し、読む値のタイプとしてxmlrpcまたはxmlrpc message(任意のタイプのXML-RPCメッセージを読む)、xmlrpc request(受信したメッセージがリクエストでない場合は例外をスローする)、またはxmlrpc response(受信したメッセージが応答またはフォールトでない場合は例外をスローする)を指定します:

read an xmlrpc message from socket clientSocket into msgRecvd
read an xmlrpc request from socket clientSocket

以下のキーが認識されます:

  • Host: 投稿先のホスト;
  • URL: ホストとリクエストURIを含む投稿先のURL;
  • ** Request: 投稿先のURI;
Important

ホストまたはURLのいずれかが必要です。リクエストがない場合のホストが与えられている場合、リクエストは "/"に設定されます。

  • User-Agent: 指定されていない場合、SenseTalkの長バージョンが提供されます;
  • Header: オプション。他のヘッダー要素;
  • Method: 必須。呼び出されるメソッドの名前;
  • Params: パラメータ値の配列。必要に応じて "as boolean", "as text" 等を指定します。

XMLRPCFormat() 関数

XML-RPCメッセージの本文内で使用するためのフォーマットが必要な任意の値を表す文字列を返します。

XMLContentEncode() 関数

"<"、">"、"&"、および単引きと二重引用符の文字をそれぞれのXMLエンティティ値に置き換えることにより、XMLドキュメントの内容に含めるための安全な形式にテキストを変換します。

XMLContentDecode() 関数

XMLContentEncode()により生成された特定のXMLエンティティ値を含む文字列をデコードし、元のテキストを返します。