Reputation: 709
My goal is to be able to chain START commands in a single cmd line.
Lets say I have a cmd window (lets call it starter). With a single line I want to start a new cmd window (lets call it cmd1) that will echo 1 and start another cmd window (lets call it cmd2) that will echo 2 and wait (with pause), after cmd1 called cmd2 (without waiting for it to finish) it will wait as well (with pause), after starter called cmd1 (without waiting for it to finish) it will close (or do nothing)
In the end I should end up with 2 cmd windows (cmd1 with "1" printed, cmd2 with 2 printed) and both are waiting for ENTER.
Running scheme:
--- Starter
+--- Start cmd1 (Non-blocking)
| +--- Start cmd2 (Non-blocking)
| | +--- Echo 2
| | \--- Pause (Blocking cmd2)
| +--- Echo 1
| \--- Pause (Blocking cmd1)
\---Do nothing (Starter, Incase running from bat file starter will exit)
I wrote this cmd line in a bat file:
title starter
start cmd.exe /c start cmd.exe /c "echo 2 & pause" & echo 1 & pause
\----------cmd2-----------/
\---------------------------cmd1----------------------------/
(the "title starter" is just for understanding which window is opened and should not be included in the final line)
with that cmd line, starter is the one that prints 2 and waits, and cmd1 just exits after calling cmd2.
The running scheme of that line:
--- Starter
+--- Start cmd1 (Non-blocking)
| \--- Start cmd2 (Non-blocking)
| +--- Echo 2
| \--- Pause (Blocking cmd2)
+--- Echo 1
+--- Pause (Blocking Starter)
\---Do nothing (Starter, Incase running from bat file starter will exit)
I tried some other variations of this line with no success.
title starter
start "cmd.exe /c start cmd.exe /c "echo 2 & pause" & echo 1 & pause"
start cmd.exe /c "start cmd.exe /c "echo 2 & pause" & echo 1 & pause"
start cmd.exe /c "start cmd.exe /c ""echo 2 & pause"" & echo 1 & pause"
(important to note that I can open the 2 cmds (cmd1, cmd2) from the first cmd (starter) and the result of this will be the final result of my wanted running scheme, but it is important that cmd1 will be the one that creates cmd2)
So, does anyone know how may I achieve the running scheme that I want?
Upvotes: 3
Views: 3307
Reputation: 130849
Here is a script that will recursively START any arbitrary number of windows. Simply pass the count as the first and only argument to the script. If you don't provide the count, then it will only open 1 window.
The technique relies on the definition of a variable named cmd
that serves as a "macro". It contains the string of commands to be executed by cmd.exe /v:on /c
. It is important that the macro not be expanded until within the child process. Within the parent batch I delay expansion of the macro by using %%cmd%%
. All subsequent processes have a command line context instead of batch context, so the delay is achieved by %^cmd%
instead. When defining the macro, the percents must be doubled as %%^cmd%%
to achieve the desired string of %^cmd%
.
RecursiveStart.bat
@echo off
setlocal disableDelayedExpansion
set /a N=1, END=%~1+0
set "cmd=set /a N+=1,N-1&echo(&(if not !N! gtr !END! start "!N!" cmd /v:on /c %%^cmd%%)&pause"
start "%N%" cmd /v:on /c %%cmd%%
For example, to start 5 windows, simply use:
RecursiveStart 5
However, if all you want to do is open N number of windows and execute some commands in each, and each window is entirely independent of the other (don't care who started it), then it is much simpler to iterate the START command N times in your parent script.
@echo off
for /l %%N in (1 1 5) do start "%%N" cmd /c "echo %%N&pause"
Upvotes: 1
Reputation: 56180
I hope, I understood your requirements right...
title Starter
start "one" cmd.exe /c "start "two" cmd.exe /c "echo 2 ^& pause" & echo 1 &pause"
The trick is proper escaping of &
to pass it through the first pass of parsing to get then parsed with the second step.
I added titles to all windows.
Upvotes: 6