[[Language]] * 目次 [#kd018898] #contents //////////////////////////////////////////////////////////////////////////////// * 共通 [#udbf4d6a] ** コメント [#m841fda8] -- "#" 以降がコメントになる -- 式を書いた後にコメントを書く場合、 "#" の前に ";" がないとエラーになるので注意 ** I/O [#k5fe58b5] - 定義済みの channel_ID: stdout / stderr / stdin - 出力 -- puts [-nonewline] channel_ID string --- defalut では stdout へ出力する。 --- -nonewline オプションをつけると、改行文字を省略する。 --- 例 puts stderr "ERROR: an error has occuered\r"; # stderr に文字列を出力。 - 入力 -- gets gets stdin VAL; # 変数 VAL に、stdin から読み取った内容を格納する。 -- read [-nonewline] channel_ID --- channel_ID から全てのデータを読み込む。 --- -nonewline オプションをつけると、改行文字を省略する。 -- read channel_ID bytes --- channel_ID から、bytes 分のデータを読み込む。 -- seek channel_ID offset [origin] --- originは、以下が定義されている: |~origin |~description | |start |ファイルやデバイスの先頭から | |current |現在のアクセス位置 | |end |ファイルやデバイスの終端から | -- tell channel_ID --- channel_ID の、現在のアクセス位置を返す。 ** 1sec 未満の sleep [#n27d57ab] - 1sec未満の sleep をするには、sleep ではなく、after を使用する。単位はmsecである。 # 50msec の sleep after 50; ** 変数 [#b8ea3b68] - 宣言 -- 宣言・代入する時は、変数名に接頭辞をつけない set AAA "1234"; -- 参照する時は、接頭辞 "$" をつける。$変数名 とするか、${変数名} と表記する。 puts "AAA: ${AAA}\r"; puts "BBB: $BBB\r"; -- ※宣言されていない変数を参照しようとすると、スクリプトabortするので注意すること。 ** 関数 [#qf190abc] - 関数定義 proc function_name { arg1 arg2 } { # 実装 return ${value}; # 返り値を返す場合 } -- 関数名は、キーワード "proc" に続けて書く -- 引数には、接頭辞(?) "$" はつけない。区切りはコンマではなくスペース - 関数呼び出し function_name ${aa} ${bb}; # 通常の呼出しの場合 set return_value [ function_name ${aa} ${bb} ]; # 返り値を取得する場合 ** グローバル変数 [#cfce567f] - グローバル領域に変数を定義し、その変数を参照する関数内で、 "global" 文にて列挙する必要がある #!/usr/bin/expect set G_VAL1 ""; proc func_name { arg1 arg2 } { global G_VAL1; if { ${arg1} > 10 } { set G_VAL1 ${arg1}; } else { set G_VAL1 ${arg2}; } } ** 他のスクリプトファイルから関数や変数を取り込む [#za16d2cc] - あるスクリプト(script-main.xとする)から、別のスクリプトファイル(script-sub.xとする)の中身を取り込みたいときは、以下のように記述する: source "script-sub.x"; -- これにより、script-sub.x の定義内容が、元からscript-main.xに書かれていたかのように扱える。 ** フロー制御 [#hb9d792c] *** if [#lf2b9949] set i 10; set EXP 20; if { ${i} > ${EXP} { 処理... } elseif { ${i} == ${EXP} } { 処理... } else { 処理... } - 動かない例: 「 } elseif { } { 」ではなく「 elseif { } {」 if { ${i} > ${EXP} } { 処理... } elseif { ${i} == ${EXP} } { 処理... } else { 処理... } *** for [#q0f54d72] set LOOP_MAX 100; for { set i } { ${i} < ${LOOP_MAX} } { incr i } { 処理... } *** foreach [#xdb5adc3] - 例1 foreach i { 0 1 2 3 4 5 } { 処理... } - 例2 foreach { i j } { 0 1 2 3 4 5 } { 処理... } - 例3 foreach i { 0 1 2 3 4 5 } j { 0 10 20 30 40 50 } { 処理... } *** while [#j842bed1] while { ${i} >= ${VAL} } { 処理... } *** ループ制御の補助コマンド [#e483400d] |~command |~description | |continue | ループをスキップ。| |break | ループを終了 | |exit [ return_code ] |return_code は、default では0 | *** switch [#fd207646] switch [options] ${string} { pattern_1 { 処理... } pattern_2 { 処理... } ... default { 処理... } } - options |~option |~description | |-exact | string と pattern が完全に一致する場合に真となる | |-glob | string をグロブパターン pattern とマッチング | |-regexp| string を正規表現 pattern とマッチング | |-- | option 終了を示す | - option 無しの場合、値 1 と 値 01 は、別物として識別される。 ** 時間 [#md0caab7] - 現在時間の取得 set time_stamp [ clock clicks -milliseconds ]; -- "-milliseconds" オプションを付けると、msecオーダーの精度が保証される。 - 上記で取得した時間の値 time_stamp を書式化して、time に格納する。 set time [ clock format ${time_stamp} -format "%s" ]; - より詳しくは、[[Lang/Tcl_Tk_Expect/time]] へ。 *** 経過時間の計測 [#x561d74a] # 経過時間計測 # 1. GetWrapTimeInit で start_ts を取得。 # 2. GetWrapTime を、 start_ts を渡して呼ぶと、現在時間との差分を返す。 proc GetWrapTimeInit { } { set start_ts [ clock clicks -milliseconds ]; set start_ts [ clock format ${start_ts} -format "%s" ]; return ${start_ts}; } proc GetWrapTime { start_ts } { set ts [ clock clicks -milliseconds ]; set ts [ clock format ${ts} -format "%s" ]; set wrap [ expr ${ts} - ${start_ts} ]; return ${wrap}; } //////////////////////////////////////////////////////////////////////////////// * expect [#f32570ee] ** シグナルを受け取った時の処理 [#q1278609] - bashのシェルスクリプトのように、"trap" コマンドを使う。 - 詳しいことは、[[expect の manpage>http://www.linux.or.jp/JM/html/expect/man1/expect.1.html]] にも書かれているので参照のこと。 書式: trap [[command] signals] - 次の例では、シグナルを受け取った時に、終期化処理を行う "terminate" 関数を定義し、それを呼び出すようにしている。 proc terminate { } { # 例えば、ログ取得を終わらせる、とか。 log_file; } trap terminate {SIGINT SIGTERM} ** log の取得 [#n927a8bf] - "log_file" コマンドとシグナルを利用すると結構便利に使える。 - 下記は、"interact" で制御をユーザに引き渡した後、 Ctrl-a でログ取得開始、Ctrl-b でログ取得終了となるようにした例。 proc LogStart { logfile } { log_file ${logfile}; puts "Logging Start: ${logfile}\r; } proc LogStop { } { puts "Logging Stop\r"; log_file; } # 処理を色々記述。 set CTRLA \001 set CTRLB \002 interact { ${CTRLA} { LogStart ${out_log}; } ${CTRLB} { LogStop; } } //////////////////////////////////////////////////////////////////////////////// * 参考リンク [#laeb8a5b] - [[もっとTcl/Tk>http://www.interq.or.jp/japan/s-imai/tcltk/index.html]]