Why Batch File wouldn't remain variable if I redirect to it instead of call it

Viewed 89

I wanna implementate OutTo.cmd which can achieve:

echo msg | OutTo.cmd var
echo %var%
msg

my code in OutTo.cmd:

set /p %1=

@REM For check
echo %var%

when I run echo msg | OutTo.cmd var, Console would display

msg

which means "msg" save into var successfully during OutTo.cmd running

but then I run echo %var%, console display nothing, which means var is not defined, after OutTo.cmd

But if I run OutTo.cmd as below:

OutTo.cmd var

and type in:

msg

after OutTo.cmd finished, var's value would remain:

echo %var%

display

msg

will, I know the easiest way is:

echo msg > tmp
set /p newvar=<tmp

So I just curious about, why batch would remain variable if I call it but not if I redirect output to it?

1 Answers

Test.cmd

@echo off
setlocal enabledelayedexpansion

echo Test.cmd
echo !cmdcmdline!

echo Call OutTo.cmd
call OutTo.cmd

echo Pipe to OutTo.cmd
echo msg | OutTo.cmd

echo Pipe to OutTo.cmd using call
echo msg | call OutTo.cmd

OutTo.cmd

@echo off
setlocal enabledelayedexpansion

echo(!cmdcmdline!

Output:

Test.cmd
cmd  /c Test.cmd
Call OutTo.cmd
cmd  /c Test.cmd
Pipe to OutTo.cmd
C:\Windows\system32\cmd.exe  /S /D /c" OutTo.cmd"
Pipe to OutTo.cmd using call
C:\Windows\system32\cmd.exe  /S /D /c" call OutTo.cmd"

This example is to display what is happening with piping and not piping.

Command used to execute Test.cmd:

cmd /c Test.cmd

Used enabledelayedexpansion so that echo of !cmdcmdline! does not cause problems if & or other unquoted special character is in the command line.

About the output:

  • The 1st command line is from Test.cmd itself.
  • The 2nd command line is call OutTo.cmd from Test.cmd. Same as the 1st as same process.
  • The 3rd command line is piping to OutTo.cmd. Not the same process as 1st and 2nd, it is a child process.
  • The 4th command line is piping to OutTo.cmd by use of call. Not the same process as 1st and 2nd, it is a child process.

The 3rd and 4th will strip the outer quotes from the command after /c as /S is used and autorun commands are disabled as /D is used.

The 4th is obsolete as using call after /c is not required. It is executed as a separate instance of cmd.exe.

The pipe causes a separate process as piping is one process piping to another process. cmd.exe is executed to run OutTo.cmd as a child process to be piped to.

A child process can inherit from a parent process. A parent process cannot inherit from a child process. The last statement is why you cannot get %var% with a value set in the OP as you are trying to get it from a child process.

Related