#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. Спасибо за подробный ответ и более оптимизированное решение.