我想实现 OutTo.cmd 可以实现:
echo msg | OutTo.cmd var
echo %var%
msg
我在 OutTo.cmd 中的代码:
set /p %1=
@REM For check
echo %var%
当我运行时
回显消息| OutTo.cmd var
,
控制台将显示
msg
这意味着OutTo.cmd运行期间“msg”成功保存到var中
但后来我跑了
echo %var%
,控制台什么都不显示,说明var没有定义,在OutTo.cmd之后
但是如果我按如下方式运行 OutTo.cmd:
OutTo.cmd var
并输入:
msg
OutTo.cmd 完成后,var 的值将保持不变:
echo %var%
显示
msg
会的,我知道最简单的方法是:
echo msg > tmp
set /p newvar=<tmp
所以我只是好奇,为什么如果我调用它,batch 会保持变量 但如果我将输出重定向到它就不会?
最佳答案
测试.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 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"
此示例显示管道和非管道发生的情况。
用于执行Test.cmd的命令:
cmd /c Test.cmd
二手enabledelayedexpansion
这样 !cmdcmdline!
的回声如果 &
则不会引起问题或命令行中存在其他未加引号的特殊字符。
关于输出:
- 第一个命令行来自 Test.cmd 本身。
- 第二个命令行是
call
来自 Test.cmd 的 OutTo.cmd。与第一个相同,过程相同。 - 第三个命令行通过管道传输到 OutTo.cmd。与第一个和第二个进程不同,它是一个子进程。
- 第四个命令行使用
call
通过管道传输到 OutTo.cmd 。与第一个和第二个进程不同,它是一个子进程。
第三个和第四个将从 /c
之后的命令中删除外引号。如/S
使用并且自动运行命令被禁用为 /D
已使用。
第四个已过时,因为使用 call
之后/c
不需要。它作为 cmd.exe 的单独实例执行。
管道会导致一个单独的进程,因为管道是一个进程管道到另一个进程。执行 cmd.exe 以将 OutTo.cmd 作为要通过管道传输到的子进程运行。
子进程可以继承父进程。父进程不能继承子进程。最后一句话就是为什么你不能得到 %var%
当您尝试从子进程获取它时,在 OP 中设置一个值。
关于batch-file - 如果我重定向到批处理文件而不是调用它,为什么批处理文件不会保持变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60584100/