ZHUOWARE BACKYARD - NOTE INDEX|ZHUOWARE BACKYARD TOP|ZHUOWARE表ページ

Tcl exec command tips

はじめに

Tclのexecコマンドは,動かすのに多少ノウハウを要する.そのtipsとして,下記が非常に参考になる. これでほぼOK!という感じなのだが,「変数に空白文字が含まれる場合や,あったりなかったりする語の,展開のさせ方」について,少しだけ補なってみた.

Feb. 22, 2009: ファイル名が"[", "]"を含む場合,下記ではevalで失敗することに気がついた.あらかじめ"[", "]"の前にescapeを挿入しておく必要がある.evalしなければよいのだが,いまのところよい方策が見つかっていない.

結局,

次のように書くとよい.setのたびにクォートや変数の展開が一段起きることを考え,evalにふさわしい形となるようコマンド文字列を構成しておいて,eval execする.
set filename "hoe hoe.tcl"
set option ""
# set option "-x"
set cmd "\"c:/program files/tcl/bin/wish84\" \"$filename\" $option"
eval exec $cmd
cmdを構成する行がポイントである.

難しい理由と,対策の手段

execの難しさとして,次のような点があげられる.
  1. コマンド名や各引数は,正しく分離されるように(間違ってくっつかないように)する必要がある.
  2. 空白文字を含む語は,正しく一体に保たれるように(間違って分離されないように)する必要がある.
  3. 語を入れたくない時には,正しく語が省かれるように(間違って「空文字列」の語が入らないように)する必要がある.
  4. バッククォートやダブルクォートが,正しく渡されるように(間違って,前処理の段階で解釈・変形されてしまわないように)する必要がある.
  5. 変数は正しく置換されるように(間違って,オリジナルのまま残らないように)する必要がある.
  6. システムごとに適合した表現になるようにする必要がある.
上記の要求を実現する手段として,次のようなものがある.

そのほか

execするときは,エラー終了することも考え,catchするのがよい.
if {[catch {eval exec $cmd} msg]} {
    puts "error: $msg"
} else {
    puts "ok: $msg"
}