Batch file 为什么批处理文件不会';如果我重定向到它而不是调用它,它就不会保持变量

Batch file 为什么批处理文件不会';如果我重定向到它而不是调用它,它就不会保持变量,batch-file,variables,cmd,pipeline,io-redirection,Batch File,Variables,Cmd,Pipeline,Io Redirection,我想实现OutTo.cmd 这可以实现: echo msg | OutTo.cmd var echo %var% msg OutTo.cmd中的我的代码: set /p %1= @REM For check echo %var% 当我跑的时候 echo msg | OutTo.cmd var, 控制台将显示 msg 这意味着在OutTo.cmd运行期间,“msg”成功保存到var中 但后来我跑了 echo%var%,控制台在OutTo.cmd之后不显示任何内容,这意味着未定义var 但如

我想实现OutTo.cmd 这可以实现:

echo msg | OutTo.cmd var
echo %var%
msg
OutTo.cmd中的我的代码:

set /p %1=

@REM For check
echo %var%
当我跑的时候
echo msg | OutTo.cmd var
, 控制台将显示

msg
这意味着在OutTo.cmd运行期间,“msg”成功保存到var中

但后来我跑了
echo%var%
,控制台在OutTo.cmd之后不显示任何内容,这意味着未定义var

但如果我运行OutTo.cmd,如下所示:

OutTo.cmd var
并键入:

msg
OutTo.cmd完成后,var的值将保持:

echo %var%
展示

msg
威尔,我知道最简单的方法是:

echo msg > tmp
set /p newvar=<tmp
echo msg>tmp
set/p newvar=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!
输出:

本示例旨在显示管道和非管道的情况

用于执行Test.cmd的命令:

已使用
启用延迟扩展
,以便响应
!CMDLINE&
或其他不带引号的特殊字符,则code>不会导致问题

关于输出:

  • 第一个命令行来自Test.cmd本身
  • 第二个命令行是Test.cmd中的
    call
    OutTo.cmd。与第一个相同,即相同的过程
  • 第三个命令行是管道到OutTo.cmd。与第一个和第二个过程不同,它是一个子过程
  • 第四个命令行是使用
    call
    将管道传输到OutTo.cmd。与第一个和第二个过程不同,它是一个子过程
当使用
/S
时,第三个和第四个命令将在
/c
后从命令中删除外部引号,当使用
/D
时,自动运行命令将被禁用

第四个已过时,因为不需要在
/c
之后使用
调用
。它作为cmd.exe的单独实例执行

管道导致一个单独的过程,因为管道是一个过程管道到另一个过程。执行cmd.exe以将OutTo.cmd作为要通过管道传输到的子进程运行


子进程可以从父进程继承。父进程不能从子进程继承。最后一条语句是当您试图从子进程获取值时,无法使用OP中设置的值获取
%var%
的原因。

调用脚本的正确用法是
调用foo.bat Argument1“Argument 2”Argument3
。在
foo.bat
中,传递给它的值将在
%1
Argument1
)、
%2
“Argument 2”
)、
%3
Argument3
)和
%*
Argument1”Argument 2“Argument3
)中可用。它们可以在
foo.bat
中使用,比如
echo%1
可能我没有表达清楚,对不起我的英语不好,我的意思是,如果我只是运行批处理文件,它将保持变量不变,但如果我将输出重定向到itA,则不会同时为任何一方启动新的
cmd.exe
实例,因此在那里设置的任何变量都会丢失(在最初的托管
cmd.exe
实例中)…我认为这是一个完美的解释,请让我理解,感谢您的帮助。原因是:直接调用/run.cmd在当前进程中运行,而管道到.cmd是子进程。
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"
cmd /c Test.cmd