💻

ファイル名に現在時刻を入れたために、robocopyが動かなかった件

2024/09/29に公開

はじめに

robocopyを使ったコマンドが、リハーサル時と本番時でうまく動かなったことがありました。エラーにもならなかったので解決に時間がかかりました。

概要

以下の2つの前提があります。

  1. DOSコマンド%time%は、時刻部分が一桁の場合ゼロパディングではなく、スペースが入ります
    • %time:~0,2%が、(例えば)2時の場合は" 2"になり、12時の場合は"12"になります
    • これを使ってコマンドを実行すると、スペースの部分で区切って認識されます
  2. robocopyの三番目の引数は任意で、ファイル名を指定して対象を絞ります

上記2つが重なって、エラーにもならずうまく動きませんでした。

REM 対象のコマンド
robocopy from to /LOG:log%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%.log

REM 12時台に動かした場合
robocopy from to /LOG:log123456.log
REM 2時台に動かした場合
robocopy from to /LOG:log 23456.log
  • robocopyのログファイル(/LOG:オプションで指定)の名前に%time:~0,2%を利用している場合、時刻によってスペースの有無が異なるため、以下のような動きになります
    • 12時の場合は/LOG:log123456.logとなり、"log123456.log"をログファイルとします
    • 2時の場合は/LOG:log 23456.logとなり、"log"をログファイル、"23456.log"を三番目の引数と認識して、"23456.log"に絞ってコピーを試みます

再現

再現するコマンドは以下になります。

REM 作業フォルダを作って移動します
md test_copy
cd test_copy

REM コピー元とコピー先フォルダを作り、コピー用ファイルを作ります
md from
md to
fsutil file createNew from\testfile.dat 1048576

REM robocopyを実行します。
REM ログファイル名に現在日時を入れます。
robocopy from to /LOG:log%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%.log

最後のrobocopyの部分を動かす時刻が0-9時の場合、概要に記載した事象が起こり、コピー用ファイルがエラーにもならずコピーされないということが起こります。

解決案はいろいろありますが、以下を参考にした案を紹介します。

https://qiita.com/koiwaiwaiko/items/b7e969a00020025c4d7e

0-9時のスペースがある際は、0に変換した文字列を変数に格納し、そこからログファイル名に使う時分秒の文字列を切り出します。

REM スペースを0に変換した時分秒を格納します。
set str_time=%time: =0%

REM robocopyを実行します。
REM ログファイル名に変数から切り出した現在日時を入れます。
robocopy from to /LOG:log%date:~0,4%%date:~5,2%%date:~8,2%%str_time:~0,2%%str_time:~3,2%%str_time:~6,2%.log

おわりに

昔から有名な問題だったようですが、私は初遭遇で本番でやらかしてしまいました。
環境変数などを文字列にして使う場合は、いったん文字列を出力して中身を確認するなどをすれば、防げたかもです。
この記事がどなたかのお役に立てれば幸いです。

Discussion