En el cmd de Windows, ¿cómo solicito la entrada del usuario y uso el resultado en otro comando?

398

Tengo un archivo .bat de Windows que me gustaría aceptar la entrada del usuario y luego usar los resultados de esa entrada como parte de la llamada a comandos adicionales.

Por ejemplo, me gustaría aceptar una ID de proceso del usuario y luego ejecutar jstack contra esa ID, colocando los resultados de la llamada de jstack en un archivo. Sin embargo, cuando intento esto, no funciona.

Aquí está mi muestra del contenido del archivo bat:

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

y esto es lo que aparece en jstack.txt:

Ingresar ID: ¿Terminar trabajo por lotes (S / N)? 
Nakilon
fuente
2
"¿Terminar trabajo por lotes (S / N)?" normalmente aparece cuando presionas ctrl-c mientras tu .bat se está ejecutando.
Jim Buck el
2
Jstack.txt contendrá la salida de jstack y nada relacionado con su archivo por lotes y tampoco ha dicho qué es Jstack.
sgmoore
1
¿Alguna de estas respuestas no funcionó? Si no, ¿encontraste una solución? Si lo hiciera, sería útil que lo publicara aquí como una respuesta propia.
Maslor
1
Si desea opciones fijas para la entrada, es mejor choiceset /p
usarlas
2
Marque mi publicación como la respuesta, cuya esencia es que, cuando ejecuta el programa por lotes, presiona Enter en lugar de proporcionar una ID en el indicador y, por lo tanto,% id% se configuró en Enter ID: lugar de alguna ID desde la que se suponía que debía proporcionar el teclado.
pashute

Respuestas:

459

Prueba esto:

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

Luego puede usarlo %id%como parámetro para otro archivo por lotes como jstack %id%.

Por ejemplo:

set /P id=Enter id: 
jstack %id% > jstack.txt
Sopa instantánea
fuente
2
¿Hay alguna manera de canalizar la salida del comando SET a NIL :, para que pueda ocultar la escritura? ¿Como si quisieras hacer un: set /p id=Enter ID:\r\n set /p pw=Enter Passwd:y no quisieras que el texto de la contraseña se muestre en la ventana, y mucho menos, que se muestre en el búfer de comando "DosKey"? He intentado varias formas diferentes, y no he podido encontrar una manera de hacerlo, aparte de escribir un pequeño programa en C para tomar la entrada y asignarla a un EnvVar, ¡pero eso es trampa! :) Quiero que funcione con SOLO CMD de Windows.
LarryF
44
Tenga en cuenta la simplicidad adicional del espacio al final de "Enter ID: ". Da un pequeño espacio dulce entre la solicitud y la respuesta del usuario. Delete the internet?No sillyvs Delete the internet? No silly.
icc97
No hay necesidad de las cotizaciones. Lo que faltaba @Instantsoup era el '% id%' en la líneajstack %id% > jstack.txt
pashute
1
Use SETLOCALy ENDLOCALsi desea mantener la variable local en el lote actual. Ver ss64.com/nt/endlocal.html
endo64
99

La sintaxis es como tal: set /p variable=[string]

Visite http://commandwindows.com/batch.htm o http://www.robvanderwoude.com/userinput.php para una inmersión más profunda en la entrada del usuario con las diferentes versiones de los archivos por lotes del sistema operativo Windows.

Una vez que haya configurado su variable, puede continuar usándola de la siguiente manera.

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

tenga en cuenta la %VariableName%sintaxis

jayfessenden
fuente
Por favor termine su oración ... ¿va a incluir otro enlace? Además, probé todo lo anterior en un cmd.exeshell de Windows 7 , y cada uno, sin excepción, asigna la entrada del usuario a una variable nombrada arbitrariamente. ¿Cómo se embellece su respuesta sobre lo que ya se ha proporcionado?
chb
3
Cuando publiqué mi respuesta, realmente no parecía que la pregunta original hubiera sido respondida. La pregunta original es "¿Cómo pides la entrada del usuario y luego la respuesta y la usas en otro comando?" Creo que mi respuesta respondió sucintamente la pregunta. Además, cuando buscas en Google "cómo obtienes la entrada del usuario de un archivo por lotes", esta pregunta es la número 2 en resultados, por lo que necesita la respuesta correcta, por lo que pensé que era este foro.
jayfessenden
14
El espacio después del =no es necesario.
Joey
¿Por qué necesitamos el espacio? ¿Qué sucede exactamente en el cmdque no deja espacio?
ytpillai
@Joey Estoy de acuerdo, la página de robvanderderwoude.com no tiene espacioSET /P variable=[promptString]
icc97
31

No estoy seguro de si este es el caso para todas las versiones de Windows, sin embargo, en la máquina XP que tengo, necesito usar lo siguiente:

set /p Var1="Prompt String"

Sin la cadena de solicitud entre comillas , obtengo varios resultados dependiendo del texto.

Daniel
fuente
+1 para "varios resultados según el texto": tuve el mismo problema. Ahora imprime las comillas con el texto, pero no hay más comportamiento extraño.
Benj
66
use esta sintaxis para tener las comillas, pero evite mostrarlas :set /p "var1=Prompt String"
Stephan
Es útil usar las comillas e incluir un espacio al final, ya que hace que la solicitud en la línea de comando sea más agradable. Tener las comillas hace obvio que hay un espacio allí en el archivo por lotes. set /p Var1="Prompt String "Luego, cuando ejecuta el archivo y el usuario escribe algo que obtiene en Prompt String Yeslugar dePrompt StringYes
icc97
22
set /p choice= "Please Select one of the above options :" 
echo '%choice%'

El espacio después =es muy importante.

Hannad Rehman
fuente
14
@echo off
set /p input="Write something, it will be used in the command "echo""
echo %input%
pause

si consigo lo que quieres, esto funciona bien. también puede usar% input% en otros comandos.

@echo off
echo Write something, it will be used in the command "echo"
set /p input=""
cls
echo %input%
pause 
fedeb
fuente
8
@echo off
:start
set /p var1="Enter first number: "
pause
Anisha Gupta
fuente
2
¿Por qué empiezas :start?
Benj
1
:startes solo un marcador ... Por ejemplo, también podría usar un :end, que hace que sucedan cosas como la limpieza de variables, o llamar a popd, o algo así. Luego, también tiene la opción de usar un IF ERRORLEVEL1 GOTO END... o incluso un GOTO ERR, y debajo :errtiene algo como eco. Ocurrió un error al intentar obtener el número de archivo. goto: end Es probablemente una
cuestión
8

No hay ningún parámetro documentado / rápido para SETX como lo hay para SET.

Si necesita solicitar una variable de entorno que sobrevivirá a los reinicios, puede usar SETX para almacenarla.

Una variable creada por SETX no será utilizable hasta que reinicie el símbolo del sistema. Sin embargo, puede configurar SETX una variable que ya ha sido SET, incluso si tiene el mismo nombre.

Esto funciona para mí en Windows 8.1 Pro:

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

(Las comillas alrededor de la variable existente son necesarias).

Este procedimiento le permite usar la variable temporal creada por SET durante la sesión actual y le permitirá reutilizar la variable creada por SETX al reiniciar la computadora o reiniciar el indicador CMD.

(Editado para formatear párrafos de código correctamente).

Timothy J. McGowan
fuente
5

Tengo un pequeño cmd que uso cuando preparo la PC para los clientes: llama al usuario para que ingrese y le cambia el nombre a la PC.

@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
fuente
Hola de nuevo, este útil script se usa en la PC Win10 después de la configuración inicial :-)
Werdna
5

Hay dos posibilidades

  1. Olvidó poner el %id%en la jstackllamada.

    jstack %id% > jstack.txt
    

Entonces, todo el archivo por lotes correcto debe ser:

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

Y / o 2. Lo colocó en el código (y olvidó decirnos en la pregunta) pero cuando ejecutó el archivo por lotes presionó la tecla Intro en lugar de escribir una ID (digamos 1234).

Lo que está sucediendo es el resultado de estos dos errores: jstackse supone que debe llamarse con la identificación que usted proporciona.

Pero en su caso (de acuerdo con el código que proporcionó en la pregunta) lo llamó sin ninguna variable. Tu escribiste:

jstack > jstack.txt

Entonces, cuando ejecuta jstacksin variable, genera lo siguiente:

Terminate batch file Y/N? 

Su segundo error es que haya pulsado Intro en lugar de dar un valor cuando el programa le preguntó: Enter ID:. Si hubiera puesto una ID en este punto, digamos 1234, la %id%variable se convertiría en ese valor, en nuestro caso 1234. Pero NO proporcionó un valor y en su lugar presionó Enter. Cuando no le das ningún valor a la variable, y si esa variable no se configuró en otra cosa antes, ¡entonces la variable %id%se configura según el indicador del setcomando! Así que ahora %id%está configurado para Enter ID:que se repita en su pantalla como se solicitó en el archivo por lotes ANTES de llamar al jstack.

Pero sospecho que TENÍA el jstack %id% > jstack.txtcódigo de su archivo por lotes con el %id(y lo omitió por error de la pregunta), y que presionó enter sin escribir una identificación. El programa por lotes se hizo eco de la identificación, que ahora es "Ingresar ID:", y luego ejecutójstack Enter ID: > jstack.txt

Jstack se hizo eco de la entrada, encontró un error y le pidió que terminara.
Y todo esto fue escrito en el archivo jstack.txt.

pashute
fuente
3

Los signos de dólar alrededor de la variable no funcionan en mi máquina Vista, pero los signos de porcentaje sí. También tenga en cuenta que se mostrará un espacio final en la línea "set" entre la solicitud y la entrada del usuario.

SRE
fuente
espacio final? win7 x64 rus: C:\>set /p DestPath="Type path:"y la siguiente línea esType path:c:\dddd
Arioch 'The
2
$ sign es para las variables bash o unix. El signo %% es para las variables de Windows.
noob
Si tiene un SETLOCAL ENABLEDELAYEDEXPANSIONarchivo por lotes, puede usarlo !EnvVariable!para expandirlo a su valor durante los bucles FOR u otras cosas que no expanden las macros hasta que el analizador Cmd procese realmente la línea. Consulte cmd /?para obtener información sobre esto, así como help setlocal...
LarryF
2

Acabo de agregar el

set /p NetworkLocation= Enter name for network?

echo %NetworkLocation% >> netlist.txt

secuencia a mi trabajo por lotes netsh. Ahora me muestra la ubicación a la que respondo como el punto para esa muestra. Continuamente >> el archivo de salida, así que ahora sé "casa", "trabajo", "Starbucks", etc. Buscando aire limpio, puedo eavular los canales de menor uso y si hay 5 o solo todas las WLAN de 2.4 MHz.

Juan
fuente
2

Solo para mantener un valor predeterminado de la variable. Presione Entrar para usar el valor predeterminado de la ejecución reciente de su .bat:

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

rem YourApp %Var1%

En la primera ejecución, simplemente ignore el mensaje sobre la falta de archivo con el valor inicial de la variable (o cree el Var1.txt manualmente).

Antoni
fuente
(set /p var=<var1.txt) 2>nulsuprimirá el mensaje de error. También puede dar en set var1=defaultlugar de obtener algo de un archivo
Stephan
Stephan, ¿la segunda parte de tu propuesta no conserva los valores entre ejecuciones? ¿Puedes desarrollarlo más?
Antoni
no, no entre carreras. Simplemente da un valor predeterminado. (no hubo ninguna solicitud para almacenar el valor entre ejecuciones en la pregunta).
Stephan