1

Say I have a filesystem like so:

Directory 1
  --dataset
Directory 2
  --dataset
Directory 3
  --dataset
process.bat
copier.bat <-- RUNS

The copier.bat copies process.bat into a directory and runs it:

Directory 1
  --dataset
  --process.bat <-- RUNS
Directory 2
  --dataset
Directory 3
  --dataset
process.bat
copier.bat

Process.bat takes a few minutes, and when it's done, copier.bat copies process.bat into the next directory and runs it:

Directory 1
  --dataset
  --process.bat
Directory 2
  --dataset
  --process.bat <-- RUNS
Directory 3
  --dataset
process.bat
copier.bat

While process.bat is running in the next directory, a new directory with another dataset is added:

Directory 1
  --dataset
  --process.bat
Directory 2
  --dataset
  --process.bat <-- RUNNING
Directory 3
  --dataset
Directory 4
  --dataset
process.bat
copier.bat

I need copier.bat to recognize Directory 4 is added while process.bat is running so it continues to copy into Directory 4 and run process.bat.

This is what copier.bat looks like right now, as it stands it will only copy into the directories present when copier.bat is first ran:

for /D %%i in (*) do (
cd %%i
copy ..\process.bat process.bat
call process.bat
cd ..
)

Code source: https://peterfalkingham.com/2018/04/01/colmap-openmvs-scripts-updated

  • Well, your code does not copy `process.bat` as you describe, it copies itself. And `for` or `for /D` does definitely not enumerate all matching files or directories on advance -- read [this thread](https://stackoverflow.com/q/31975093)... – aschipfl Mar 29 '19 at 13:33
  • Anyway, why do you copy a sub-script into each directory? can't you just let a single script do all the tasks? You could let it create a log that indicates what directories have been processed and let it process only those items not present in the log, and let it even recheck against the log after having finished processing the initially enumerated directories, so you can assure all directories have been processed when the script quits... – aschipfl Mar 29 '19 at 13:47
  • Oops, it was a long day. Fixed the example so it copies process.bat – Josh Carstens Mar 30 '19 at 14:27

1 Answers1

1
@echo off
setlocal

:main
call :myCopier
if not errorlevel 1 goto :main

exit /b 0


:myCopier
setlocal
set "batfile=process.bat"
set "exitcode=1"

for /D %%A in (*) do (
    if not exist "%%~A\%batfile%" pushd "%%~A" && (
        set "exitcode=0"
        copy "..\%batfile%" "%batfile%" && call "%batfile%"
        popd
    )
)

exit /b %exitcode%

You are copying copier.bat in your code though copying process.bat in you directory structure listings. I consider the later as logically correct.

This code will call the label :myCopier in the :main loop until %errorlevel% is not 0.

It will do Directory 1, Directory 2 and Directory 3 on 1st call :myCopier. %errorlevel% returned is 0 so it does another call :myCopier. This time Directory 4 is processed. %errorlevel% returned is 0 so it does another call :myCopier. All directories will have process.bat within, so the %errorlevel% returned is 1. This allows the end of the :main loop.

With your other script. Perhaps you should insert a setlocal to keep it's enviroment local to itself. Also insert double quotes around paths so spaces or special characters do not cause problems.

michael_heath
  • 5,262
  • 2
  • 12
  • 22