Systemwalker Centric Manager スクリプトガイド - UNIX/Windows(R)共通 - |
目次 索引 |
第2章 文法 | > 2.3 Systemwalkerスクリプトで使用するコマンド・制御文 |
サブプロセスを起動し、プログラムのコマンドを実行します。
【Windows版】
exec cmd /c cmdname 【args …】 |
注) execコマンドは、cmd /cと併せて使用してください。
【UNIX版】
exec cmdname 【args …】 |
最後のargsが“&”の場合、コマンドはバックグラウンドで実行されます。コマンドは通常、フォアグラウンドで実行され、execコマンドはcmdnameのプロセス終了を待ちますが、バックグラウンドで実行した場合は、終了を待たずに復帰します。
また、argsにはフロー制御記号を指定することが可能です。
Windowsの場合、ファイルをパス指定で与えるときは、ディレクトリの区切りに“\”(円記号)を使用してファイル名全体を“{ }”(中括弧)で囲む必要があります。
argsに以下のフロー制御記号を記述することで、起動コマンドの標準入出力への操作や複数コマンドを起動しての情報のやりとりが可能となります。
記号・書式 |
意味 |
例 |
| |
パイプライン中の個々のコマンドを区切ります。前のコマンドの標準出力を後のコマンドの標準入力へつなげます。同様にして3つ以上のコマンドをつないでいくことが可能です。 |
【Windows版】 【UNIX版】 |
< filename |
cmdnameの標準入力として、filenameで指定したファイルの内容が読み込まれます。(注1) |
【Windows版】 【UNIX版】 |
<< value |
cmdnameの標準入力として、valueで指定した値(文字列)が読み込まれます。(注1) |
【Windows版】 【UNIX版】 |
> filename |
cmdnameの標準出力がfilenameで指定したファイルに上書きで書き込まれます。(注1) |
【Windows版】 【UNIX版】 |
>& filename |
cmdnameの標準出力と標準エラー出力がfilenameで指定したファイルに上書きで書き込まれます。(注1) |
【Windows版】 【UNIX版】 |
2> filename |
cmdnameの標準エラー出力がfilenameで指定したファイルに上書きで書き込まれます。(注2) |
【Windows版】 【UNIX版】 |
注1:cmdnameの部分が“|”により複数のコマンドからなる場合、読み込みは先頭のコマンドが、書き込みは末尾のコマンドがその対象となります。
注2:cmdnameの部分が“|”により複数のコマンドからなる場合、すべてのコマンドの標準エラー出力がfilenameで指定したファイルに格納されます。
フロー制御により複数のコマンドが実行される場合は、末尾のコマンドがその対象となります。
また、フロー制御により標準出力がリダイレクトされている場合は、空文字列を返します。
フロー制御により複数のコマンドが実行される場合は、全プロセスIDが空白で区切って返されます。
アプリケーションが出力する標準出力を、execコマンドの復帰値として獲得することはできません。
【Windows版】
#アプリケーションを起動します。標準出力を変数"outmsg"に格納します。 #アプリケーションが標準出力へ出力したデータをジョブの標準出力へ出力します。 #アプリケーションの実行まで正常に完了した場合は、終了コード"0"で終了します。 |
【UNIX版】
#アプリケーションを起動します。標準出力を変数“outmsg”に格納します。 #アプリケーションが標準出力へ出力したデータをジョブの標準出力へ出力します。 #アプリケーションの実行まで正常に完了した場合は、終了コード“0”で終了します。 |
注) catchによる処理例外設定がないため、execで起動したコマンドが、“0”以外の終了コードで終了したり、異常終了した場合に以下の問題が発生します。
これらを回避するために、コマンドを起動する際にはcatchコマンドによる処理例外のトラップをすることを推奨します。
標準出力/標準エラー出力情報(errorInfo)について
コマンドの標準出力/標準エラー出力がリダイレクトされていない場合、グローバル変数errorInfoの先頭にその出力文字列が格納されます。errorInfoには、exec文自身の実行エラーを示す文字列も格納されます。例:
【Windows版】以下の仕様のアプリケーション(c:\usr\bin\appl001.exe)がエラー終了した場合
仕様:指定された日付のデータを標準出力に書き込む。 日付の指定が不当な場合は以下のメッセージを標準エラー出力に出力する。 “日付の指定に誤りがあります。yyyymmdd で指定してください。”
if {[catch {
exec cmd /c {c:\usr\bin\appl001.exe} 010520
}]} {
puts "エラー情報 START"
puts $errorInfo
puts "エラー情報 END"
}上記を実行すると、標準出力には以下のように表示されます。
エラー情報START
日付の指定に誤りがあります。yyyymmddで指定してください。←appl001コマンドの出力
while executing ← exec文自身の実行エラーを
"exec cmd /c {c:\usr\bin\appl001.exe} 010520" ← 示す文字列
エラー情報END【UNIX版】
存在しないファイル(/tmp/data)を指定し、lsコマンドを実行する場合
if {[catch {
exec ls /tmp/data
}]} {
puts "エラー情報 START"
puts $errorInfo
puts "エラー情報 END"
}上記を実行すると、標準出力には以下のように表示されます。
エラー情報 START
/tmp/data: ファイルもディレクトリもありません。 ← lsコマンドの出力
while executing ← exec文自身の実行エラーを
"exec ls /tmp/data" ← 示す文字列
エラー情報 END
終了コード(errorCode)について
コマンドの終了コードが“0”以外の場合は、グローバル変数errorCodeに以下の書式で終了コードが格納されています。また、その他の詳細情報も格納されます。 errorCodeの書式については、“catch(スクリプト行を実行し処理例外をトラップする)”の復帰値を参照してください。
CHILDSTATUS pid exitcode
- pid
- 【Windows版】
- ここに入る数字は意味を持ちません。
- 【UNIX版】
- プロセスID
- exitcode
- プロセスの終了コード
実行コマンドのリダイレクトされていない入出力は以下のとおりに扱われます。
入出力 |
フォアグラウンド実行 |
バックグラウンド実行 |
標準入力 |
スクリプトプロセス自身の標準入力から読み込まれる。 | |
標準出力 |
通常は、execコマンドの戻り値となる。 |
スクリプトプロセス自身の標準出力に書き込まれる。 |
標準エラー出力 |
execコマンドの処理例外として扱われ、catchでトラップした場合にはerrorInfoに格納される。 |
スクリプトプロセス自身の標準エラー出力に書き込まれる。 |
catch
例:
exec cmd /c swctclsh {c:\script\part1.swt} |
なお、execコマンドを複数回数呼び出すスクリプトを作成した場合は、スクリプトの動作確認時に最大回数までのexec呼出しを実施して、すべての呼出しが正常に行われることを確認してください。
以下の条件をすべて満たした場合、直接起動したコマンドが終了しても復帰しません。
したがって、デーモン起動シェルなど常駐するプロセス起動を行なう場合は、以下のようにバックグランドで起動するか、標準出力と標準エラー出力をファイル等にリダイレクトするようにしてください。
exec rdbstart & |
exec rdbstart >& /tmp/log.txt |
exec rdbstart >& /dev/null |
Windowsのプログラムには、コマンドのオプションのダブルコーテーションなどを特別な文字として解釈する一般的なコマンドと、そういった解釈をしない特殊なコマンドがあります。そのような特殊なコマンドには、スクリプト自身もダブルコーテーションの解釈を行っているため、パラメタを正しく渡せない場合があります。
一般的なコマンドのパラメタ解釈例
コマンドラインの記述 |
コマンド内での解釈 |
|
"abc" |
→ |
abc |
\"abc\" |
→ |
"abc" |
特殊なコマンドは、コマンドラインの記述をそのまま解釈します。
特別な文字を解釈しないコマンドを実行させる場合は、コマンドを実行するバッチファイルを作成し、そのバッチファイルをexecで実行するように記述してください。
execから起動したコマンドや、そのコマンドから更に起動されたプロセスが動作中の間は、swctclshは終了せずに起動中のままになります。
フロー制御記号(< > 2>)から始まる文字列は、引数に指定した場合フロー制御記号として解釈されるため、文字列として渡すことはできません。以下のどちらかの方法で指定してください。
文字列として解釈させるために、先頭に半角空白を付加した文字列に変えて引数に指定します。
文字列が変数(msgtxt)に格納されている場合、以下のように記述することで、先頭に半角空白を付加することができます。
if {[regexp {^<|^>|^2>} $msgtxt] == 1} { |
目的のコマンドを起動するシェルスクリプト(UNIX版)またはバッチファイル(Windows版)をスクリプト内で作成し、それをexecコマンドで起動させるようにします。ただし、引数文字列内にダブルコーテーション(")が含まれていると、シェルスクリプトやバッチファイル内での文字列解釈が正しく行われなくなるため、引数文字列中に含まれるダブルコーテーションをシングルコーテーション(')にあらかじめ置き換えます。
例:コマンド(usercmd)の引数に、任意の文字列が格納されている変数(msgtxt)を指定して起動させます。
【UNIX版】
“/tmp/usercmd_tmp.sh”は、一時的に作成するシェルスクリプトで、実行後に削除します。
if {[regexp {^<|^>|^2>} $msgtxt all] == 1} { |
【Windows版】
“c:\temp\usercmd_tmp.bat”は、一時的に作成するバッチファイルで、実行後に削除します。
if {[regexp {^<|^>|^2>} $msgtxt all] == 1} { |
【Windows版】
dirコマンドを実行し、コマンドの標準出力/標準エラー出力をすべてスクリプトの標準出力へ出力させます。
if {[catch {
set outmsg [exec cmd /c dir {c:\tmp\data}]
# dirの標準出力(exec戻り値)をスクリプトの標準出力へ
puts stdout $outmsg
}]} {
# 処理例外発生
# outmsgには初期値として$errorInfoを格納しておきます。
set outmsg $errorInfo
# dirの出力情報(errorInfoの末尾2行を除いたもの)をスクリプトの標準出力へ
regexp {(.*)\n.*\n.*} $errorInfo all outmsg
puts stdout $outmsg
}
【UNIX版】
lsコマンドを実行し、コマンドの標準出力/標準エラー出力をすべてスクリプトの標準出力へ出力させます。
if {[catch {
set outmsg [exec ls -l /tmp/data]
# lsの標準出力(exec戻り値)をスクリプトの標準出力へ
puts stdout $outmsg
}]} {
# 処理例外発生
# outmsgには初期値として$errorInfoを格納しておきます。
set outmsg $errorInfo
# lsの出力情報(errorInfoの末尾2行を除いたもの)をスクリプトの標準出力へ
regexp {(.*)\n.*\n.*} $errorInfo all outmsg
puts stdout $outmsg
}
標準出力には、以下のように表示されます。
【Windows版】
ドライブ C のボリューム ラベルはありません。 |
ドライブ C のボリューム ラベルはありません。 |
【UNIX版】
-rw-rw-r-- 1 root other 0 9月 25日 15:05 /tmp/data |
/tmp/data: ファイルもディレクトリもありません。 |
目次 索引 |