execコマンドの疑問について
 Tcl/TkはもともとUNIX計算機をターゲットに開発されたので、 動作がシステムに大きく影響するexecコマンドもUNIXがベースになっていて、 MS-Windowsでは少し混乱することがあります。 Tcl/Tkの開発陣もできるだけ機種に依存しないように工夫しようとされているようですが、 さすがにどうしても一貫性がとれないところもあるようです。 ここでは主にMS-Windowsでよく出会うexecコマンドの疑問について並べてみました。
  • 実行できない
    
    set cmd "notepad.exe hoehoe.txt"
    
    exec $cmd
    
    
    とすると「notepad.exe hoehoe.txt が見つからない」 というエラーになります。これはTcl処理系が "notepad.exe hoehoe.txt" という名前の実行ファイルを探しているためです。 期待通りに notepad.exe を実行ファイル、hoehoe.txtをその引数と解釈してもらうには、
    
    eval exec $cmd
    
    
    とします。evalコマンドでまず展開するのがみそです。

  • 大文字小文字
    UNIX上のwishはファイル名の大文字小文字を区別しますが、 MS-Windows上のwishは区別しません。 それぞれのシステムの仕様に一致するように配慮されています。

  • パスの区切り
    UNIXではパスの区切りは /文字が、MS-Windowsでは \文字が使われますが、MS-Windows上のTclでは \文字と/文字の好きなほうをパスの区切りとして使うことができます。
    
    \program files\tcl\bin\wish81.exe
    
    /program files/tcl/bin/wish81.exe
    
    
    ただしコマンドライン引数のパスをどう解釈するかは execコマンドで呼び出すアプリケーション次第ですから、 注意が必要です。

  • バッチファイルは実行できる?
    できます。
    
    set command "C:/windows/command /c AAA.bat"
    
    set result [eval exec $command]
    
    
    簡単、簡単。

  • ファイルパスのバックスラッシュは何重にすればいいの?
    アプリケーションの引数としてファイルパスにバックスラッシュを使う場合には、 「eval exec」の引数になった時点でバックスラッシュが二重になるように、 逆算していきます。ファイルパスを直接リテラル書きする場合には二重、 一旦変数に格納する場合なら四重に書きます。以下、 setコマンドが使われるたびに2つのバックスラッシュが 1つに縮むので、それまでに3回の代入が発生する場合なら、 最初の定義で実に十六重のバックスラッシュを書いておかないといけないことになります。
    
        set PERL   "C:\\\\usr\\\\local\\\\Perl\\\\bin\\\\perl"
    
        set SCRIPT "C:\\\\home\\\\watasi\\\\script.pl"
    
        set cmd "$PERL $SCRIPT a.file"
    
        eval exec $cmd
    
    
    これは1回代入があるので、最初の時点で四重に書いています。

  • 長いファイル名
    Windows版のTcl/TkではDOS(8+3)形式とWin32(長いファイル名) 形式の両方をサポートしています。ですから
    
    eval exec "{/Program Files/Tcl/bin/wish82.exe} $SCRIPTFILE"
    
    eval exec "/Progra~1/Tcl/bin/wish82.exe $SCRIPTFILE"
    
    
    はどちらも通ります。

  • 空白を含んだファイル名
    UNIXではファイル名にスペースが含まれることは極めてまれで、 またわざわざそんな名前をつける機会もありませんが、 MS-Windowsでは「Program Files」のように間にスペースを含むディレクトリがあり、 これの解釈が結構悩むところです。先の例のように、
    
    set cmd "/program files/tcl/bin/wish81.exe hoehoe.tcl"
    
    eval exec $cmd
    
    
    としたのでは、実行ファイル「/program」がないというエラー になってしまいます。正解は
    
    set cmd "{/program files/tcl/bin/wish81.exe} hoehoe.tcl"
    
    eval exec $cmd
    
    
    です。中括弧とダブルクォートの位置に注意すれば簡単ですね。

  • バックグラウンド実行させるには
    exec コマンドを使うと、 通常は呼び出されたアプリケーションが終了するまで呼び出したTclスクリプトは動作が完全に停止します。 ボタンに反応することもありませんし、 だいいち再描画に反応できないためウィンドウが固まったようになってしまいます。 しかしマルチタスク環境では当然、呼び出されたアプリケーションと呼び出したTclスクリプトが同時に完全に動作してほしいもの。 この解決法は、 UNIXのXウィンドウシステムに慣れている方ならおなじみですが、 MS-Windowsではちょっと奇異に思われるかもしれません。 それはコマンドライン引数の最後にアンパサンド(&)文字をつけることです。
    
    set cmd "notepad.exe hoehoe.txt &"
    
    eval exec $cmd
    
    
    これでメモ帳でファイルを編集しつつ、 もとのTclスクリプトも完全に動作を続けることができます。 また、これもXウィンドウシステムならおなじみのことですが、 呼び出したほう(ここではTclスクリプト) が呼び出されたほう(ここではメモ帳)より先に終了しても、 呼び出されたほうが一緒に終了させられてしまう、 ということはありません。

  • SUSIE32のようなプログラムを呼び出すと?
    MS-Windowsでは、アプリケーションによって、 2つ以上同時に起動しようとすると最初に起動したウィンドウが それ以降の起動をすべて管理するもの (ウィンドウやタスクバー項目が1つしか出ないもの) と起動した回数だけ別々のウィンドウが開いてしまうものがあります。 SUSIE32など画像関係のソフト、高機能文書エディタなどの多くは前者、 メモ帳や意外にもWordやExcelは後者です。 この動作がどうなるかはアプリケーションに完全にお任せです。

やねうらの top
(first uploaded (forgotten) last updated 2000/03/18 , Urano398 )