Почему пакетный файл не останется переменным, если я перенаправлю его вместо вызова - PullRequest
2 голосов
/ 08 марта 2020

Я хочу реализовать 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

, что означает, что "msg" успешно сохраняется в var во время работы OutTo.cmd

, но затем я запускаю echo %var%, на консоли ничего не отображается, что означает, что var не определен, после OutTo.cmd

Но если я запусту OutTo.cmd, как показано ниже:

OutTo.cmd var

и введите:

msg

после завершения OutTo.cmd, значение var останется:

echo %var%

display

msg

, я знаю, что самый простой способ:

echo msg > tmp
set /p newvar=<tmp

Так что мне просто интересно, почему пакет останется переменным, если я вызову если нет, если я перенаправлю вывод на него?

1 Ответ

4 голосов
/ 08 марта 2020

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
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! не вызывают проблемы, если & или другой специальный символ без кавычек находится в командной строке.

О выводе:

  • 1-ая командная строка из самого Test.cmd.
  • 2-ой командной строкой является call OutTo.cmd из Test.cmd. То же, что и 1-й, что и тот же процесс.
  • 3-я командная строка передает в OutTo.cmd. Это не тот же процесс, что и 1-го и 2-го, это дочерний процесс.
  • Четвертая командная строка передает в OutTo.cmd команду call. Не тот же процесс, что и 1-го и 2-го, это дочерний процесс.

3-й и 4-й извлекают внешние кавычки из команды после /c, так как используется /S и команды автозапуска отключено, так как используется /D.

Четвёртое устарело, так как использование call после /c не требуется. Он выполняется как отдельный экземпляр cmd.exe.

Канал вызывает отдельный процесс, так как конвейерная передача - это одна конвейерная передача процесса другому. cmd.exe выполняется для запуска OutTo.cmd в качестве дочернего процесса, к которому необходимо передать по конвейеру.

Дочерний процесс может наследоваться от родительского процесса. Родительский процесс не может наследоваться от дочернего процесса. Последнее утверждение объясняет, почему вы не можете получить %var% со значением, установленным в OP, так как вы пытаетесь получить его от дочернего процесса.

...