1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

.bat バッチファイルでファイルのタイムスタンプを更新する touch コマンドの代わり

Posted at

これは何

Windows のバッチファイルで、ファイルのタイムスタンプを更新する方法を紹介します。

  • できること
    • 空ファイルの作成
    • ファイルのタイムスタンプ更新
  • できないこと
    • オプションを使うこと。タイムスタンプを指定時刻に変更したりできません
    • ディレクトリのタイムスタンプを更新すること
  • 多分できないこと
    • ネットワークパスのファイルに対する touch 操作。試せてないのでわかりません。誰か、成功したら教えて

想定読者

WSL 、 cygwinmsys2 を Windows に install したくない人
外部ツールにできるだけ依存したくない人

結論

touch.bat
@echo off
if "%~1"=="" exit /b 0
if "\\.\"=="%~dp1" exit /b 0
pushd "%~dp1"
if not exist "%~nx1" (
  copy nul "%~nx1">nul
) else if not exist "%~nx1\" (
  copy /B /Y "%~nx1"+>nul
)
if errorlevel 1 (
  popd
  exit /b %errorlevel%
)
popd
exit /b 0

実行例

正しい使い方

通常のファイルに対する touch 操作は、成功すると 0 が返ります。
アクセス権限等で失敗すると非0が返ります。

通常のファイルに対する touch

C:\a>dir
2019/10/12  00:27    <DIR>          .
2019/10/12  00:27    <DIR>          ..
C:\a>touch.bat foo.txt
C:\a>echo %errorlevel%
0
C:\a>dir
2019/10/12  00:27    <DIR>          .
2019/10/12  00:27    <DIR>          ..
2019/10/12  00:27                 0 foo.txt
C:\a>touch.bat foo.txt
C:\a>echo %errorlevel%
0
C:\a>dir
2019/10/12  00:27    <DIR>          .
2019/10/12  00:27    <DIR>          ..
2019/10/12  00:30                 0 foo.txt

読み取り専用ファイルに対する touch

読み取り専用属性を付与した foo.txt に対する touch

C:\a>touch.bat foo.txt
アクセスが拒否されました。
C:\a>echo %errorlevel%
1

正しくない使い方

特殊ファイルやディレクトリ等、 touch.bat が対応していないファイルに対する touch は 0 が返ります。

特殊ファイルに対する touch

C:\a>touch.bat nul
C:\a>echo %errorlevel%
0

ディレクトリに対する touch

C:\a>mkdir bar
C:\a>touch.bat bar
C:\a>echo %errorlevel%
0

雑談

バッチファイルの変数展開は、文を評価するタイミング展開されてしまうので、 if 文や for 文の中で変数を更新しようとすると、色々と面倒臭くて嫌いだった。しかし、touch.batを作成していて、初めて便利だと思った。
それは、copy が失敗したときの復帰処理が書きやすかったことです。
復帰処理は、copy の戻り値を呼び出し元に転送しつつ、popdを実行して元のディレクトリに戻る必要があります。つまり、copy の戻り値を exit /b の引数に渡しつつ、popdの実行をすることになります。if文の中で popdexit /b %errorlevel% を実行すると、if文を評価するタイミングで %errorlevel% が評価されるので、exit /b の引数に指定した %errorlevel%popd の英共を受けません。その結果、中間変数に %errorlevel% の値を保持する必要はなくなります。素晴らしい。
バッチファイルで一時変数を使う場合、 setlocal しないと環境変数が汚れるので、できるだけ使いたくありません。その点でも良いと思いました。

参考リンク

【Windows】空のファイルを作成する(Linuxで言うtouch)
Windows OSでファイルの最終変更時刻を更新する(touchコマンドを実現する)
batファイルでコマンドの実行結果を出力しないようにする方法
How to test if a path is a file or directory in Windows batch file?

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?