Tera Termマクロで用意されているfilesearchコマンドはファイルが存在するとシステム変数resultに1を格納しますが、困ったことにそれがディレクトリであっても同じくシステム変数resultに1を格納します。
foldersearchと組み合わせれば良さそうですが、面倒です。どうせなら1度で済ませたいですよね。
という事で、ぼくの解決方法を紹介します。
2016/09/26追記:ぼくの解決方法は正しくなかったので、正しい方法について追記しています。詳細についてはチケット#36643を参照してください。
ファイルステータスを取得するコマンド
filestatはTera Term 4.66以降で使用できるコマンドです。このコマンドは、ファイルのサイズや最終変更時刻、ドライブ番号を取得します。使い方は次のようになります。
filestat <filename> <size> [<mtime>] [<drive>]
filenameにステータスを取得したいファイル名、sizeはfilenameのファイルサイズが入ります。mtimeとdriveは指定しなくても大丈夫です。
このコマンドは、ファイルステータスの取得に失敗するとシステム変数resultに-1が格納されます。
という事で、このコマンドを使えばファイルの存在確認ができそうですね。サンプルです。
;ファイルの存在を確認するサンプル ; 存在確認するファイル filename = 'hoge.txt' size = 0 filestat filename size if result == -1 then messagebox 'ファイルが存在しない' size else messagebox 'ファイルが存在する' size endif
もしもディレクトリだったら?
これはこれで動くのですが、filestatは万が一ファイルでなくディレクトであった場合でもシステム変数resultは-1にならず、ファイルが存在するときと同様に0が格納されます。
ファイルとディレクトリを一発で判別する正しい方法
チケット#36643で紹介されているマクロは以下のようなものです。
name = "C:\test" getfileattr name if result < 0 then messagebox "not found" name elseif result & $10 then messagebox "directory" name else messagebox "file" name endif
getfileattrはTera Term 4.69以降で使う事ができるTTLコマンドです。次のように使います。
getfileattr <filename>
filenameで指定したファイルの属性を取得します。属性の取得に失敗した場合はシステム変数resultに-1が格納されます。成功すると、属性値がシステム変数resultへ格納されます。
属性値 | 意味 |
$1 | 読み取り専用 |
$2 | 隠しファイルまたは隠しディレクトリ |
$4 | オペレーティングシステムの一部、またはオペレーティングシステム専用 |
$10 | ディレクトリ |
$20 | アーカイブ |
$80 | 特に属性はない |
$100 | 一時ファイル |
$200 | スパースファイル |
$400 | 再解析ポイントが関連付けられているか、シンボリックリンク |
$800 | 圧縮されている |
$1000 | オフラインの記憶装置へ物理的に移動された(Windows 2000 以降) |
$2000 | 「インデックスサービス」の対象になっていない(Windows 2000 以降) |
$4000 | 暗号化されている |
属性値の頭に「$」が付いているのは、16進数という意味です。値の判定に使っている箇所
elseif result & $10 then
この「&」はビット演算子です。「&&」とは意味が違うので注意してください。ビット演算子はTera Term 4.53以降で使う事ができます。16進数やビット演算子についてピンと来ない方もいるかと思いますが、分からなくても大丈夫です。「result & $xxx」で属性が取得できる、という理解で十分です。「$xxx」の箇所は上の表に書いてある値を入れます。たとえば読み取り専用か知りたければ「result & $1」で調べる事ができます。
ぼくが紹介していた正しくない方法
2016/09/26追記:この方法、今のところは動くのですが正しいやり方ではありません。今後仕様変更があった際に誤作動を招く恐れがあるので、真似しないで下さいね!
では、どうやって解決すれば良いのかというと、ディレクトリの場合はsizeに0が格納されます。ですので、システム変数resultとファイルサイズが両方とも0であった場合はディレクトリ、システム変数resultが0でファイルサイズが0超過であればファイルであると判断できます。サンプルです。
;ファイルの存在を確認するサンプル ; 存在確認するファイル filename = 'hoge.txt' size = 0 filestat filename size if result == -1 then messagebox 'ファイルが存在しない' size elseif result == 0 && size == 0 then messagebox 'ディレクトリです' size else messagebox 'ファイルが存在します' size endif
さいごに
getfileattrについては、完全に見落としていました。これならばファイルなのか、ディレクトリなのか、といった判別だけでなく属性を調べる事ができるので応用範囲が広がりそうです。
2016/09/18追記
昨日(2016/09/17)、OSDNにこのページに関するチケットが上がっていました。
チケットを起票して、プロジェクト内でも議論しましたが、
filestatのサイズがゼロかどうかでは、ディレクトリかどうか判別しては
ならない、という結論となりました。
記事の訂正をお願いします。
適切な判別方法については、下記チケットを参照願います。
https://osdn.jp/ticket/browse.php?group_id=1412&tid=36643
ご指摘ありがとうございます。記事を修正しました。ぼくと同じような事をしている人がいるかも知れないので、正しくない方法は削除せずに悪い例として残しています。
早速の対応ありがとうございました。