Поведение команды echo с оператором канала в Windows?

#windows #batch-file

#Windows #пакетный файл

Вопрос:

Я хотел создать пакетный файл для печати значения переменной, передав имя переменной через аргумент командной строки ex.

 print.bat username
 

содержимое print.bat

 @echo off
setlocal
set v=%%%1%%%
echo | echo %v%
 

Хотя сценарий работает отлично, но я все еще не понимаю, как работает

 echo | echo %v%
 

Мое понимание каналов заключается в том, что Вывод первой команды (т. Е. Команды в левой части оператора канала) передается второй команде (т. Е. Команде Справа от оператора канала), поэтому в соответствии с этим должен быть правильный путь echo %v% | echo (который не работает).

Кто-нибудь может объяснить это поведение?

Спасибо

Комментарии:

1. Echo не считывает стандартный ввод. Независимо от того, почему вы думаете, что вам нужно передавать пустое эхо в другую команду echo? Может быть, вы пытаетесь сделать: echo.amp;echo %v% ??

2. @Squashman — похоже, он действует так call , что это невероятно странно, поскольку я бы тоже не ожидал echo принимать ввод по каналу.

Ответ №1:

 set v=%%%1%%%
 

%1 в вашем примере это первый аргумент, переданный в командной строке username . Затем %% при разборе строки они уменьшаются вдвое, а одиночная % строка в конце отбрасывается, оставляя v значение set %username% равным .

 echo | echo %v%
 

echo %v% анализируется как echo %username% , но канал заставляет его выполняться во втором экземпляре интерпретатора, где он проходит еще один раунд синтаксического анализа, который расширяется %username% до значения переменной username среды.

правильный способ должен был быть echo %v% | echo (который не работает)

Это не работает и не может работать, поскольку echo не использует стандартный входной поток. Вывод первой echo %v% команды отбрасывается, а вторая echo не находит аргументов командной строки, поэтому она выводит обычное ECHO is on .

Ключевым моментом здесь является то, что первый echo in echo | echo %v% фактически не используется как echo . Его единственная роль — разрешить канал, что, в свою очередь, вызывает повторный анализ второй echo команды. Например type nul | echo %v% , будет работать точно так же.

Однако это можно было бы сделать дешевле без ненужного конвейера, используя call .

 @echo off
setlocal
set "v=%%%1%%"
call echo %v%
 

Комментарии:

1. Спасибо за подробный ответ и более оптимизированное решение.