0

I am trying to modify some excellent code for multithreading batch commands, by dbenham : Parallel execution of shell processes (should not be required to read to solve my problem).

It currently takes the commands from reading a file reference. I want to instead send the commands in via arguments. This will basically only need a single for loop to be modified.

The problem is no matter what variations I try I can not get the correct split out of the for-loop. I am obviously missing something basic with delimiters or something despite reading the documentation multiple times. This is likely pretty trivial for a more experienced batch scripter I expect, but I am thoroughly stuck...

I am certain that the only thing that needs to change is a single for-statement:

(snippet of multithread.bat)

 for /f "tokens=* delims=:" %%A in ('findstr /b ":::" "%~f0"') do (

This currently does : "Search in the calling script file (from %~f0) for any lines starting with ::: and make each of those %%A in the for-loop". This works great, but...

I want to modify this to instead take the lines (commands) from arguments, preferably by just parsing from %* (all arguments). The input format and order of arguments are arbitrary so feel free to change it as you want if it makes more sense another way.

Let me illustrate with a basic example how it might look in practice:

(main script - for illustration)

::these are the commands we want to run, ideally I'd like to support an arbitrary number of them
set command1="rclone size remote1:"
set command2="rclone size remote2:"
set command3="rclone size remote3:"

call multithread.bat /O 2 %command1% %command2% %command3%

:: /O indicates we ask for more verbose output from the command controller
:: 2 indicates the desired max amount of conurrently running threads
:: We just want to skip these in the for-loop as they are picked up elsewhere in the script.

So what should that for-loop look like to make %%A be command 1,2,3 (and ect. if more commands) ? For example, in the first run of the loop, %%A should in this example be:

rclone size remote1:

then...

rclone size remote2:

the second time ect.

TheStigma
  • 11
  • 2
  • Your strategy of passing multiple commands on the command line will greatly limit the complexity of your commands - you won't be able to pass commands that take quoted arguments. – dbenham Oct 30 '19 at 02:47

1 Answers1

0

You could use for %%a in (%*) do ..., but you would have to disregard the first two arguments. Let me suggest another approach:

@echo off
setlocal enabledelayedexpansion   
set "verbose=%~1"
set "max="%~2"
shift&shift
echo Verbose=%verbose%
echo Maximum=%max%
:loop
if "%~1"=="" goto :continue
echo execute command: %~1
shift
goto :loop
:continue
echo done.

Execute as test.bat /O 2 "rclone size remote1:" "rclone size remote2:" "rclone size remote3:"

Stephan
  • 53,940
  • 10
  • 58
  • 91
  • Thanks, this approach works well. I think I over-complicated it by trying to use for /F with lots of options to do what I needed. To add something constructive here, I might explain that "shift" moves all arguments forward 1 step. Making %2 be the new %1 ect. This is something I did not know until recently, so maybe it will help someone else who reads this :) – TheStigma Oct 30 '19 at 01:07
  • Yes, from time to time, we all are falling into this trap. To be honest, a `for` loop *is* the most obvious approach. But sometimes, "the good old way" fits better. – Stephan Oct 30 '19 at 08:03