バッチの二重起動を防止したり、実行順序を制御したりするために、touchコマンドでロックファイルを作成させたいことがある。標準のWindows OSにはtouchコマンドはないが、同等のことは実現可能である。その方法を紹介する。
対象OS:Windows 7/Windows 8.1/Windows 10/Windows Server 2008 R2/Windows Server 2012/Windows Server 2012 R2/Windows Server 2016
バッチなどのスクリプトを利用する場合、長さ0(ゼロ)バイトのファイルを使って、実行を制御することがある。
例えば、ある処理の開始時に、特定の名前を持つファイル(ロックファイル)を作成しておき、処理が終了した時点でそのファイルを削除する。すると、間違えて処理を二重に起動しようとしても、そのファイルが存在する場合は処理中なので、後から起動した方は処理を中断することができる。
また、「バッチ処理A」が成功終了した時点で特定のファイルを作成しておき、後続の「バッチ処理B」は、そのファイルが存在する場合にのみ処理を開始する、といったように記述しておけば、簡単に排他や順序制御が実現可能だ。
このような目的で利用されるファイルは、ファイルの内容は特に問われないので、長さ0バイトのファイルが使われることが多い(0以外でもよいのだが、0だと無駄にディスクなどのリソースを消費しないですむので、これがよく使われる)。またログファイルなどの初期状態として、長さ0バイトのファイルを用意しておくこともある。
LinuxやUNIXでは、長さ0バイトのファイルは「touch <ファイル名>」というコマンドで作成できる。touchコマンドは、本来はファイルの最終更新日時などを指定した時刻(指定がなければ現在時刻)に更新するためのコマンドだが、存在しないファイル名の場合は、ファイルを作成するという機能も持つ。
Windows OSのバッチなどでもこのようなファイルを利用したいことがあるが、残念ながらtouchコマンドはデフォルトでは用意されていない。だが、同等の機能を実現することは可能である。本TIPSでは、このような方法を幾つか紹介する。
なお、ファイルの作成や更新時刻情報を変更するという、本来のtouchコマンドのような使い方については、今後別TIPSで紹介する。
copyコマンドのコピー元として「nul」という名前のデバイスを利用できる。nulデバイスを読み出そうとしても中身は空なので(長さ0バイト。データは何も得られない)、これをコピー元にし、作成したいファイルをコピー先にしてcopyコマンドを実行すると、長さ0バイトで、最終更新日付が現在時刻となっているファイルを作成できる。すでにファイルが存在する場合は確認メッセージが表示されて煩わしいので、/yオプションを付けて、無条件で上書きさせるとよい。
このようなコマンド名が分かりづらいというならば、上述のコマンドをバッチファイルにして、touch.cmdなどの名前で保存しておけばよい。
長さ0バイトではなく、2バイトでも構わないなら、echoコマンドをリダイレクトさせてファイルを作成するという方法もある。
引数なしで単にechoコマンドを実行すると、「ECHO は <ON> です。」(および、末尾にCR-LFという改行コード)が表示されるが、「echo.」というふうにechoに続けてすぐに「.(ピリオド)」とリダイレクト指定を付けると(間に空白などを入れないこと)、CR-LFという改行コードだけがファイルに保存される。
Linuxなどでは「echo -n」とすると改行コードを抑制できるのだが、Windows OSのコマンドプロンプトの場合は、このオプションをサポートしていないので、次善の策として、これが利用できる。
PowerShellなら、New-Itemというコマンドレットを使うと、長さ0バイトの新しいファイルを作成できる。バッチファイル中から使いたいなら、「powershell new-item <ファイル名>」としてPowerShellを呼び出せば簡単だ。
LinuxやUNIXのtouchを使いたいなら、本物のLinuxのtouchコマンドを呼び出せば簡単だ。Windows OS向けに移植されたtouchコマンドも多数あるが、Windows 10ならWSL(Windows Subsystem for Linux)上のtouchを呼び出すとよいだろう。
上記のTIPSを参考にWSLをWindows 10上で利用できるようにしてから、コマンドプロンプト上で先頭に「wsl」を付けて「wsl touch <ファイル名>」のようにすればよい。
WSLを呼び出す場合、ファイルを作成する場所がカレントフォルダ以外の場合はパスが異なることがあるので注意する必要がある。例えば「C:\prj\app1\file.log」というファイルを作成したい場合は、WSL側では「/mnt/c/prj/app1/file1.log」となる。分かりづらければ、先にローカル側でchdirを使って移動しておいてからWSLを呼び出したり、相対パスだけを使って指定したりすればよいだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.