How to execute DOSKEY macros from within a batch file
Moderator: DosItHelp
Re: How to execute DOSKEY macros from within a batch file
Aaah.I see now.
Thanks.
Thanks.
Re: How to execute DOSKEY macros from within a batch file
I've done some timing tests, and the results are really dissapointing
I've tested on two machines, and each DOSKEY operation used to either store or retrieve a value takes 10 - 15 msec. That quickly adds up.
I use three DOSKEY operations to transfer a single value across the ENDLOCAL barrier - 1) set the value as a macro, 2) retrieve the value into a variable, 3) clear the macro definition. So that amounts to 30 - 45 msec to transfer a single value. Ugh
Dave Benham
I've tested on two machines, and each DOSKEY operation used to either store or retrieve a value takes 10 - 15 msec. That quickly adds up.
I use three DOSKEY operations to transfer a single value across the ENDLOCAL barrier - 1) set the value as a macro, 2) retrieve the value into a variable, 3) clear the macro definition. So that amounts to 30 - 45 msec to transfer a single value. Ugh
Dave Benham
Re: How to execute DOSKEY macros from within a batch file
Even if it's really slow it's impressive that it can tranfer data across cmd child processes and also parallel processes (started by start /b cmd).
This can be used instead of temporary files to inter process communication.
Btw.
I tested also different ways like piping and redirecting commands to cmd.exe, but still I can't get start a DOSKEY macro from a batch file.
The only thing I discoverd is that doskey consumes or breaks a redirection but not a pipe.
I'm using this test file
But for this, the output is "complete"
This can be used instead of temporary files to inter process communication.
Btw.
I tested also different ways like piping and redirecting commands to cmd.exe, but still I can't get start a DOSKEY macro from a batch file.
The only thing I discoverd is that doskey consumes or breaks a redirection but not a pipe.
I'm using this test file
test.txt wrote:echo off
echo one %time%
doskey ls=dir
echo two %time%
ls
doskey /macros
echo three %time%
Code: Select all
< test.txt cmd.exe
Output wrote:C:\temp>echo off
echo one %time%
one 0:03:16,35
doskey ls=dir
But for this, the output is "complete"
Code: Select all
type test.txt | cmd.exe
Output wrote:C:\temp>echo off
echo one %time%
one 0:03:16,35
doskey ls=dir
echo two %time%
two 0:04:27,67
ls
Der Befehl "ls" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
doskey /macros
ls=dir
echo three %time%
three 0:04:27,70
Re: How to execute DOSKEY macros from within a batch file
jeb wrote:Even if it's really slow it's impressive that it can tranfer data across cmd child processes and also parallel processes (started by start /b cmd).
This can be used instead of temporary files to inter process communication.
Good idea (as long as you are talking about processes started with START /B)
One nice aspect is it eliminates the need to establish a unique path for a temporary file. Each console window gets its own copy of DOSKEY memory, so there is no worry about collisions.
I am curious what happens when two processes within the same console attempt to access DOSKEY at the exact same time, especially if they are both writing to the same "macro" name.
EDIT:
Interesting - collisions don't appear to cause any error. I'm assuming the following must result in some collisions, or else DOSKEY must have some type of queue mechanism:
test.bat
Code: Select all
@echo off
for /l %%N in (1 1 50) do (
doskey /exename=test test=%1
for /f %%A in ('doskey /m:test') do echo %1: %%A
)
exit
Output of simultaneous runs on a single processor, single core machine
Code: Select all
D:\test>start /b test.bat A&start /b test.bat B
D:\test>B: test=B
A: test=B
A: test=A
A: test=A
A: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=B
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=B
B: test=A
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
B: test=B
B: test=B
B: test=B
I also ran the test on a quad core machine, and got similar results.
Dave Benham
Last edited by dbenham on 03 Jun 2015 00:06, edited 1 time in total.
Re: How to execute DOSKEY macros from within a batch file
A doskey macro works when it is executed via JScript's SendKeys:
Tested on Windows 8
Antonio
Code: Select all
@set @a=0 /*
@echo off
set SendKeys=CScript //nologo //E:JScript "%~F0"
doskey ls=dir
echo Direct macro name:
ls
echo/
echo Via JScript's SendKeys:
%SendKeys% "ls{ENTER}"
goto :EOF
*/
WScript.CreateObject("WScript.Shell").SendKeys(WScript.Arguments(0));
Tested on Windows 8
Antonio
Re: How to execute DOSKEY macros from within a batch file
Aacini wrote:A doskey macro works when it is executed via JScript's SendKeys:
Great idea
It's so obvious that it never comes to my mind
But still I would prefere a solution without SendKeys, to be faster and not to rely on the focus.
Re: How to execute DOSKEY macros from within a batch file
Plus it only works in the command line context after the batch script has terminated.
You could get it to work within a new CMD process, while the batch is still running, if you use:
Dave Benham
You could get it to work within a new CMD process, while the batch is still running, if you use:
Code: Select all
%SendKeys% "ls{enter}exit{enter}"|cmd /q
Dave Benham
Re: How to execute DOSKEY macros from within a batch file
the character ( and ) are not processed in any special with me. the quote is encoded, the default return variables and * and ?. Previously explored safe return techniques could be adopted to preserve problematic characters, yes.dbenham wrote:Interesting idea tooComplexEd
I couldn't follow your first post - you definitely lived up to your nickname
Your second post set me on the right path, but it was missing a few details. You still need a FOR /F to transfer the DOSKEY macro value to a normal environment variable. Unfortunately, this leads to a limitation in that ! (and possibly ^) will be corrupted if the caller has delayed expansion enabled. Previously explored safe return techniques could be adopted to preserve problematic characters.
I encode the caret ^ and !, yes. The encoding causes the variable to grow, I had to use multiple doskey variables to represent a single variable.dbenham wrote:Here is a demonstration showing how two variables could be passed across the ENDLOCAL border. This also demonstrates the limitation when delayed expansion is enabled:Code: Select all
@echo off
setlocal disableDelayedExpansion
echo DelayedExpansion=OFF
echo --------------------
call :test
echo After Return:
set var
echo(
setlocal enableDelayedExpansion
echo DelayedExpansion=ON
echo --------------------
call :test
echo After Return:
set var
echo(
exit /b
:test
setlocal enableDelayedExpansion
:: Define local variables
set "var1=Hello^world"
set "var2="This ^& that" & the other thing^! ^^"
echo Before return:
set var
echo(
:: Save the local values for transport across ENDLOCAL
for %%V in (var1 var2) do doskey /exename=vars %%V=!%%V!
endlocal
echo After ENDLOCAL:
set var
echo(
:: Restore the values and undefine the DOSKEY "macros"
for /f "delims=" %%V in ('doskey /m:vars') do (
set "%%V"
for /f "delims==" %%V in ("%%V") do (doskey /exename=vars %%V=)
)
exit /b
--OUTPUT--Code: Select all
DelayedExpansion=OFF
--------------------
Before return:
var1=Hello^world
var2="This & that" & the other thing! ^
After ENDLOCAL:
Environment variable var not defined
After Return:
var1=Hello^world
var2="This & that" & the other thing! ^
DelayedExpansion=ON
--------------------
Before return:
var1=Hello^world
var2="This & that" & the other thing! ^
After ENDLOCAL:
var1=Hello^world
var2="This & that" & the other thing! ^
After Return:
var1=Hello^world
var2="This & that" & the other thing
This is one of those functions I didn't longer use but knew they were of some value, although I didn't really knew what to do with it, the idea was to free memory and have my batch run faster again, but it never reduced memory, as I expected. At that time I didn't knew empty memory is not released from cmd.EXE. I only explored the behind endlocal functionality. I never thought about doskey memory communication between parallel processes.
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: How to execute DOSKEY macros from within a batch file
dbenham wrote:jeb wrote:Even if it's really slow it's impressive that it can tranfer data across cmd child processes and also parallel processes (started by start /b cmd).
This can be used instead of temporary files to inter process communication.
Good idea (as long as you are talking about processes started with START /B)
One nice aspect is it eliminates the need to establish a unique path for a temporary file. Each console window gets its own copy of DOSKEY memory, so there is no worry about collisions.
I am curious what happens when two processes within the same console attempt to access DOSKEY at the exact same time, especially if they are both writing to the same "macro" name.
EDIT:
Interesting - collisions don't appear to cause any error. I'm assuming the following must result in some collisions, or else DOSKEY must have some type of queue mechanism:
test.batCode: Select all
@echo off
for /l %%N in (1 1 50) do (
doskey /exename=test test=%1
for /f %%A in ('doskey /m:test') do echo %1: %%A
)
exit
Output of simultaneous runs on a single processor, single core machineCode: Select all
D:\test>start /b test.bat A&start /b test.bat B
D:\test>B: test=B
A: test=B
A: test=A
A: test=A
A: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=B
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=A
B: test=A
A: test=B
B: test=A
A: test=B
B: test=A
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
A: test=B
B: test=B
B: test=B
B: test=B
B: test=B
I also ran the test on a quad core machine, and got similar results.
Dave Benham
A more approfondite test:
Process 1: process the even numbers and use the shared variable SUM for sum the corrent number.
Process 2: process the odd numbers (esample: 1 3 5 7 ...) and sum the number in the doskey variable SUM.
Final checksum 1+2+3+4+5+6+......+N=(1+N)*N/2
Run the process at maximum speed and if there are collisions unmanaged this can be view.
anyone can generate code to do the test ?
einstein1969