В Windows cmd как запросить ввод пользователя и использовать результат в другой команде?

398

У меня есть файл Windows .bat, который я хотел бы принять от пользователя, а затем использовать результаты этого ввода как часть вызова дополнительных команд.

Например, я хотел бы принять идентификатор процесса от пользователя, а затем запустить jstack для этого идентификатора, поместив результаты вызова jstack в файл. Однако, когда я пытаюсь это сделать, это не работает.

Вот мой пример содержимого файла bat:

@echo off
set /p id=Enter ID: 
echo %id%
jstack > jstack.txt

и вот что появляется в jstack.txt:

Введите ID: завершить пакетное задание (Y / N)? 
Nakilon
источник
2
"Завершить пакетное задание (Да / Нет)?" обычно появляется, когда вы нажимаете Ctrl-C во время работы вашего .bat.
Джим Бак
2
Jstack.txt будет содержать выходные данные jstack и ничего, касающееся вашего пакетного файла, а также вы не сказали, что такое Jstack.
sgmoore
1
Разве ни один из этих ответов не сработал? Если нет, вы нашли решение? Если вы это сделали, было бы полезно, если бы вы разместили его здесь в качестве самостоятельного ответа.
Маслор
1
Если вы хотите , фиксированные параметры для входа вы лучше использовать , choiceчемset /p
icc97
2
Пожалуйста, пометьте мой пост как ответ, суть которого заключается в том, что при запуске пакетной программы вы нажимаете Enter, а не вводите идентификатор в приглашении, и поэтому для% id% было задано значение, Enter ID: а не какой-то идентификатор, который вы должны были предоставить клавиатура.
пашуте

Ответы:

459

Попробуй это:

@echo off
set /p id="Enter ID: "

Затем вы можете использовать %id%в качестве параметра для другого командного файла, как jstack %id%.

Например:

set /P id=Enter id: 
jstack %id% > jstack.txt
Instantsoup
источник
2
Есть ли способ передать вывод команды SET в NIL:, чтобы вы могли скрыть ввод? Например, если вы хотите сделать: set /p id=Enter ID:\r\n set /p pw=Enter Passwd:и не хотите, чтобы текст пароля отображался в окне, не говоря уже о том, чтобы отображаться в буфере команд «DosKey»? Я пробовал несколько разных способов, и не смог найти способ сделать это, кроме написания маленькой C-программы, которая бы взяла ввод и присвоила его EnvVar, но это обман! :) Я хочу, чтобы он работал только с CMD Windows.
LarryF
@LarryF ознакомьтесь со stackoverflow.com/questions/19950620/… и stackoverflow.com/questions/664957/…
Instantsoup
4
Обратите внимание на добавленную тонкость пространства в конце "Enter ID: ". Дает небольшой промежуток между подсказкой и ответом пользователя. Delete the internet?No sillyпротив Delete the internet? No silly.
icc97
Нет необходимости в цитатах. Чего не хватало @Instantsoup, так это «% id%» в строкеjstack %id% > jstack.txt
pashute
1
Используйте SETLOCALи, ENDLOCALесли вы хотите, чтобы переменная оставалась локальной для текущего пакета. См. Ss64.com/nt/endlocal.html
endo64
99

Синтаксис таков: set /p variable=[string]

Посетите http://commandwindows.com/batch.htm или http://www.robvanderwoude.com/userinput.php для более глубокого погружения в пользовательский ввод с различными версиями пакетных файлов ОС Windows.

После того, как вы установили свою переменную, вы можете использовать ее следующим образом.

@echo off
set /p UserInputPath=What Directory would you like?
cd C:\%UserInputPath%

обратите внимание на %VariableName%синтаксис

jayfessenden
источник
Пожалуйста, закончите предложение ... Вы собираетесь включить другую ссылку? Кроме того, я протестировал все вышеперечисленное в cmd.exeоболочке Windows 7 , и каждый - без исключения - назначает пользовательский ввод для переменной с произвольным именем. Как ваш ответ украшает то, что уже было предоставлено?
ЦБ
3
Когда я отправил свой ответ, он не выглядел так, как будто на первоначальный вопрос был дан ответ Первоначальный вопрос: «Как вы запрашиваете ввод данных пользователем, а затем делаете оборот и используете его в другой команде?» Я считаю, что мой ответ лаконично ответил на вопрос. Плюс, когда вы ищете в Google «как вы получаете пользовательский ввод из командного файла», этот вопрос # 2 в результатах, поэтому он нуждается в правильном ответе, для которого я думал, что этот форум был для.
jayfessenden
14
Пробел после =не обязателен.
Джои
Зачем нам пространство? Что именно происходит в том, cmdчто не позволяет места?
ytpillai
@ Джой, я согласен, на странице robvanderderwoude.com нет местаSET /P variable=[promptString]
icc97
31

Я не уверен, так ли это для всех версий Windows, однако на машине с XP у меня должно быть следующее:

set /p Var1="Prompt String"

Без строки подсказки в кавычках я получаю различные результаты в зависимости от текста.

Даниил
источник
+1 за «различные результаты в зависимости от текста»: у меня была та же проблема. Теперь он печатает цитаты с текстом, но странного поведения больше нет.
Бендж
6
используйте этот синтаксис, чтобы получить кавычки, но не показывайте их:set /p "var1=Prompt String"
Стефан
Полезно использовать кавычки и включать пробел в конце, поскольку это делает запрос в командной строке приятнее. Наличие кавычек делает очевидным, что в командном файле есть место. set /p Var1="Prompt String "Затем, когда вы запускаете файл и пользователь вводит что-то, что вы получаете Prompt String YesвместоPrompt StringYes
icc97
22
set /p choice= "Please Select one of the above options :" 
echo '%choice%'

Пространство после =очень важно.

Ханнад Рехман
источник
14
@echo off
set /p input="Write something, it will be used in the command "echo""
echo %input%
pause

если я получу то, что вы хотите, это прекрасно работает. Вы также можете использовать% input% в других командах.

@echo off
echo Write something, it will be used in the command "echo"
set /p input=""
cls
echo %input%
pause 
fedeb
источник
8
@echo off
:start
set /p var1="Enter first number: "
pause
Аниша Гупта
источник
2
Почему вы начинаете с :start?
Бендж
1
:startэто просто маркер ... Например, он может также использовать a :end, который вызывает такие вещи, как очистка переменной, или вызов popd, или что-то в этом роде. Кроме того, у вас также есть возможность использовать IF ERRORLEVEL1 GOTO END... или даже a GOTO ERR, и в нем :errесть что-то вроде эха. Произошла ошибка при попытке получить номер файла. goto: end Это, вероятно, вопрос привычки ...
LarryF
8

Для SETX нет задокументированного параметра / параметра приглашения, как для SET.

Если вам нужно запросить переменную окружения, которая выживет после перезагрузки, вы можете использовать SETX для ее хранения.

Переменная, созданная SETX, не будет использоваться, пока вы не перезапустите командную строку. Тем не менее, вы можете установить SETX для переменной, которая уже была SET, даже если она имеет то же имя.

Это работает для меня в Windows 8.1 Pro:

set /p UserInfo= "What is your name?  "
setx UserInfo "%UserInfo%"

(Кавычки вокруг существующей переменной необходимы.)

Эта процедура позволяет вам использовать временную переменную, созданную SET, во время текущего сеанса и позволит вам повторно использовать переменную, созданную SETX, после перезагрузки компьютера или перезапуска приглашения CMD.

(Отредактировано для правильного форматирования абзацев кода.)

Тимоти Дж. Макгоуэн
источник
5

У меня есть маленький cmd, который я использую при подготовке компьютера к клиентам: он вызывает пользователя для ввода и переименовывает компьютер в него.

@ECHO "remember to run this as admin."
@ECHO OFF
SET /P _inputname= Please enter an computername:
@ECHO Du intastede "%_inputname%"
@ECHO "The pc will restart after this"
pause
@ECHO OFF
wmic computersystem where name="%COMPUTERNAME%" call rename name="%_inputname%"

shutdown -r -f
Werdna
источник
Привет еще раз! Этот полезный скрипт используется на ПК с Win10 после начальной настройки :-)
Werdna
5

Есть две возможности.

  1. Вы забыли поставить %id%в jstackвызове.

    jstack %id% > jstack.txt
    

Таким образом, весь правильный пакетный файл должен быть:

@echo off
set /p id=Enter ID: 
echo %id%
jstack %id% > jstack.txt

И / или 2. Вы поместили его в код (и забыли сообщить нам вопрос), но когда вы запустили пакетный файл, вы нажали клавишу Enter вместо ввода идентификатора (скажем, 1234).

То, что происходит, является результатом этих двух ошибок: jstackпредполагается, что он вызывается с идентификатором, который вы ему предоставили.

Но в вашем случае (в соответствии с кодом, который вы указали в вопросе) вы назвали его без какой-либо переменной. Вы написали:

jstack > jstack.txt

Поэтому, когда вы работаете jstackбез переменных, выдается следующее:

Terminate batch file Y/N? 

Ваша вторая ошибка состоит в том, что вы нажали Enter вместо того значения , когда программа спрашивает вас: Enter ID:. Если бы вы в этот момент ввели идентификатор, скажем, 1234, %id%переменная стала бы этим значением, в нашем случае 1234. Но вы НЕ указали значение и вместо этого нажали Enter. Когда вы не даете переменной никакого значения, и если для этой переменной ранее не было установлено ничего, тогда переменная %id%устанавливается на приглашение setкоманды !! Так что теперь %id%установлено значение, Enter ID:которое было отображено на вашем экране в соответствии с запросом в командном файле ДО того, как вы вызвали jstack.

Но я подозреваю, что jstack %id% > jstack.txtу вас в коде командного файла был код %id(и он опущен по ошибке из вопроса), и что вы нажали ввод, не вводя идентификатор. Затем пакетная программа повторила идентификатор, который теперь является «Enter ID:», и затем запустилаjstack Enter ID: > jstack.txt

Jstack сам повторил ввод, обнаружил ошибку и попросил прекратить.
И все это было записано в файл jstack.txt.

pashute
источник
3

Знаки доллара вокруг переменной не работают на моей машине Vista, но знаки процента работают. Также обратите внимание, что между строкой подсказки и вводом пользователя появится завершающий пробел в строке «set».

SRE
источник
замыкающий пробел? win7 x64 rus: C:\>set /p DestPath="Type path:"и следующая строкаType path:c:\dddd
Arioch 'The
2
Знак $ для переменных bash или unix. Знак %% предназначен для переменных Windows.
Noob
Если у вас есть SETLOCAL ENABLEDELAYEDEXPANSIONпакетный файл, вы можете использовать его !EnvVariable!для расширения до его значения во время циклов FOR или других вещей, которые не расширяют макросы, пока строка не будет фактически обработана синтаксическим анализатором Cmd. См. cmd /?Информацию об этом, а также help setlocal...
LarryF
2

Просто добавил

set /p NetworkLocation= Enter name for network?

echo %NetworkLocation% >> netlist.txt

последовательность моего netsh пакетной работы. Теперь он показывает мне местоположение, на которое я отвечаю, как точку для этого образца. Я постоянно >> выводил файл, так что теперь я знаю, что такое «дом», «работа», «Starbucks» и т. Д. В поисках чистого воздуха я могу определить каналы с самым низким уровнем использования и есть ли 5 ​​или только все 2,4 МГц WLAN вокруг.

Джон
источник
2

Просто чтобы сохранить значение по умолчанию для переменной. Нажмите Enter, чтобы использовать значение по умолчанию из последнего запуска вашего .bat:

@echo off
set /p Var1=<Var1.txt
set /p Var1="Enter new value ("%Var1%") "
echo %Var1%> Var1.txt

rem YourApp %Var1%

При первом запуске просто проигнорируйте сообщение об отсутствии файла с начальным значением переменной (или создайте Var1.txt вручную).

Antoni
источник
(set /p var=<var1.txt) 2>nulбудет подавлять сообщение об ошибке. Вы также можете дать set var1=defaultвместо того, чтобы получить что-то из файла
Stephan
Стефан, вторая часть вашего предложения не сохраняет значения между запусками !? Вы можете развить это больше?
Антони
нет, не между пробегами. Это просто дает значение по умолчанию. (не было запроса на сохранение значения между прогонами в вопросе).
Стефан