Есть что-то очень странное в том, как SET /P взаимодействует с вашим конвейерным вводом, что я не совсем понимаю.
Но у меня есть несколько решений :-)
Самое простое решение — записать ваши ответы во временный файл, а затем использовать этот временный файл в качестве перенаправленного ввода.
@echo off
(
echo test
echo test
echo y
echo y
)>responses.temp
call sign_apks.bat <responses.temp
delete responses.temp
Вот так бы я решил вашу проблему. Но некоторые люди не любят использовать временные файлы (почему не знаю). Поэтому я решил попытаться решить эту проблему, используя канал без временного файла.
Я обнаружил странный вариант вашего кода, который почти решает проблему, но добавляет лишний ненужный пробел в конце каждого значения.
@echo off
(
call echo test1
call echo test2
call echo y1
call echo y2
) | sign_apks.bat
--ВЫХОД--
Enter job name: Enter key alias: Sign mobile? (y/n): Sign wear? (y/n):
"test1 "
"test2 "
"y1 "
"y2 "
Я не могу объяснить, почему CALL позволяет правильно работать каждому из операторов SET /P. Но я могу объяснить, почему к каждому значению добавляется пробел. Это связано с тем, почему CALL не нужен, когда вы используете пакетный скрипт с каналом.
Каждая сторона канала выполняется в новом сеансе cmd.exe. Например, правая сторона канала становится командой, которая выглядит примерно так:
C:\Windows\system32\cmd.exe /S /D /c" sign_apks.bat"
По этой причине CALL не нужен - управление вернется после завершения нового сеанса cmd.exe.
Нежелательные пробелы являются артефактом того, как конвейеры обрабатывают блоки в скобках. Синтаксический анализатор должен захватить весь переданный блок кода и преобразовать его в одну строку, которую можно включить в аргумент CMD.EXE /C. Синтаксический анализатор CMD.EXE делает это, помещая & между каждой командой. К сожалению, парсер также вставляет лишние пробелы. Таким образом, левая сторона трубы превращается во что-то вроде:
C:\Windows\system32\cmd.exe /S /D /c" ( call echo test & call echo test & call echo y & call echo y )"
Теперь вы можете легко увидеть, откуда берутся нежелательные конечные пробелы. Дополнительную информацию о реализации каналов см. в разделе Почему отложенное расширение завершается сбоем внутри переданного блока кода?.
Наконец-то я придумал еще одно решение. Я создал вспомогательный пакетный скрипт под названием WriteArgs.bat, который просто повторяет каждый переданный ему аргумент.
WriteArgs.bat
@echo off
:loop
if .%1 equ . exit /b
echo %1
shift /1
goto loop
С помощью этого простого пакетного скрипта теперь вы можете решить свою проблему, используя:
WriteArgs.bat test test y y | sign_apks.bat
Опять же, я не понимаю, почему SET /P работает правильно здесь, но не работает с вашей исходной командой. Но это решает проблему :-)
Обновление – Ну, оно решает проблему на моей машине. Но, похоже, это проблема времени, и я не уверен, что какое-либо заданное конвейерное решение всегда будет работать. Единственное решение, которое я считаю надежным, — это то, которое использует временный файл и перенаправление.
person
dbenham
schedule
23.12.2014