Como posso fazer um prompt “tem certeza” em um batchfile do Windows?

94

Eu tenho um arquivo em lote que automatiza a cópia de um monte de arquivos de um lugar para outro e de volta para mim. A única coisa é que eu continuo selecionando acidentalmente aquele comando do meu buffer de comando e substituindo em massa as alterações não confirmadas.

Qual código eu preciso para meu arquivo .bat para dizer "tem certeza" e me fazer digitar "y" antes de executar o resto do arquivo? Se qualquer coisa exceto "y" for digitado, ele deve sair da execução nessa linha.

Editar 27 de novembro Ok, marquei de novo como sem resposta porque ainda não consigo descobrir. Quando eu chamo "sair;" ele fecha o cmd.exe, que não é o que desejo. Tudo isso porque o Windows implementou o buffer de comando errado [diferente do que estou acostumado, pelo menos]

Josh Ribakoff
fonte

Respostas:

168

Você quer algo como:

@echo off
setlocal
:PROMPT
SET /P AREYOUSURE=Are you sure (Y/[N])?
IF /I "%AREYOUSURE%" NEQ "Y" GOTO END

echo ... rest of file ...


:END
endlocal
Joe
fonte
5
A única coisa que eu adicionaria é um adicional SET AREYOUSURE=Nantes do prompt para limpar a escolha se você já executou o script antes na janela de comando. Sem ele, o padrão permanecerá a escolha selecionada anteriormente.
isapir
4
@Igal Tenho certeza de que o setlocale o endlocaldevem cuidar disso. %AREYOUSURE%não existirá mais após o endlocal.
1
@dudeprgm você provavelmente está certo. Acho que perdi aqueles no meu código.
isapir
2
... seria mais valioso com algumas palavras explicativas sobre as duas linhas importantes .
Wolf
@Joe Talvez ele não consiga porque (como eu) ele (ainda) não os entende. Então, se você fizer isso, seria incrível se você pudesse expandir sua resposta ou link para recursos explicando isso :)
Marcus Mangelsdorf
32

tente o comando CHOICE , por exemplo

CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."
Steven A. Lowe
fonte
8
<show off> Embora isso seja relativamente novo. Foi adicionado ao MS-DOS 6 em 1993 ou 1994, então pode não funcionar com todas as implementações </ show off>
Nathan Fellman
7
exemplo de como usar a escolha aqui computerhope.com/issues/ch001674.htm
Matthew Lock
15

O choicecomando não está disponível em todos os lugares. Com as versões mais recentes do Windows, o setcomando tem a /popção de obter a entrada do usuário

SET /P variable=[promptString]

veja set /?para mais informações

ghostdog74
fonte
... muito mais perspicaz do que o aceito, mas obviamente vivemos em tempos urgentes.
Wolf
8

Existem dois comandos disponíveis para prompts do usuário na linha de comando do Windows:

  • definido com opção /Pdisponível em todas as versões do Windows NT com extensões de comando habilitadas e
  • choice.exe disponível por padrão no Windows Vista e versões posteriores do Windows para usuários de PC e no Windows Server 2003 e versões de servidor posteriores do Windows.

conjunto é um comando interno do processador de comandos do Windows cmd.exe. A opção /Pde solicitar uma string ao usuário está disponível apenas com extensões de comando habilitadas que são habilitadas por padrão, caso contrário quase nenhum arquivo em lote funcionaria mais hoje em dia.

choice.exe é um aplicativo de console separado (comando externo) localizado em%SystemRoot%\System32 . choice.exedo Windows Server 2003 pode ser copiado para o diretório %SystemRoot%\System32em uma máquina com Windows XP para uso no Windows XP como muitos outros comandos não disponíveis por padrão no Windows XP, mas disponíveis por padrão no Windows Server 2003.

É uma prática recomendada favorecer o uso de CHOICE sobre o uso de SET / P pelos seguintes motivos:

  1. CHOICE aceita apenas chaves (respectivamente caracteres lidos de STDIN ) especificadas após a opção /C(e Ctrl+C) e emite um bipe de erro se o usuário pressionar uma tecla errada.
  2. CHOICE não requer o pressionamento de nenhuma outra tecla além das aceitáveis. CHOICE sai imediatamente uma vez que uma tecla aceitável é pressionada enquanto SET / P requer que o usuário termine a entrada comRETURN ou ENTER.
  3. É possível com CHOICE definir uma opção padrão e um tempo limite para continuar automaticamente com a opção padrão após alguns segundos sem esperar pelo usuário.
  4. A saída é melhor em responder a solicitação automaticamente a partir de outro arquivo batch que chama o arquivo de lote com o prompt usando algo como echo Y | call PromptExample.batsobre o uso de ESCOLHA .
  5. A avaliação da escolha do usuário é muito mais fácil com CHOICE porque CHOICE sai com um valor de acordo com a tecla pressionada (caractere) que é atribuído a ERRORLEVEL que pode ser facilmente avaliado a seguir.
  6. A variável de ambiente usada em SET / P não é definida se o usuário pressiona apenas a tecla RETURNou ENTERe não foi definida antes de solicitar ao usuário. A variável de ambiente usada na linha de comando SET / P mantém seu valor atual se definido antes e o usuário pressiona apenas RETURNou ENTER.
  7. O usuário tem a liberdade de inserir qualquer coisa ao ser solicitado com SET / P, incluindo uma string que resulta posteriormente em uma saída da execução do arquivo em lote por cmdcausa de um erro de sintaxe, ou na execução de comandos não incluídos no arquivo em lote ou não bom arquivo em lote codificado. É necessário algum esforço para proteger o SET / P contra entrada do usuário intencionalmente errada ou por engano.

Aqui está um exemplo aviso usando preferido CHOICE e, alternativamente SET / P em choice.exenão disponível no computador usado com o Windows.

@echo off
echo This is an example for prompting a user.
echo/
if exist "%SystemRoot%\System32\choice.exe" goto UseChoice

setlocal EnableExtensions EnableDelayedExpansion
:UseSetPrompt
set "UserChoice=N"
set /P "UserChoice=Are you sure [Y/N]? "
set "UserChoice=!UserChoice: =!"
if /I "!UserChoice!" == "N" endlocal & goto :EOF
if /I not "!UserChoice!" == "Y" goto UseSetPrompt
endlocal
goto Continue

:UseChoice
%SystemRoot%\System32\choice.exe /C YN /N /M "Are you sure [Y/N]? "
if errorlevel 2 goto :EOF

:Continue
echo So your are sure. Okay, let's go ...

Nota: Este arquivo em lote usa extensões de comando que não estão disponíveis no Windows 95/98 / ME em command.comvez de cmd.execomo interpretador de comando.

A linha de comando set "UserChoice=!UserChoice: =!"é adicionada para possibilitar a chamada desse arquivo em lote echo Y | call PromptExample.batno Windows NT4 / 2000 / XP e não requer o uso de echo Y| call PromptExample.bat. Ele exclui todos os espaços da string lida de STDIN antes de executar as duas comparações de string.

echo Y | call PromptExample.batresulta em YSPACE sendo atribuído à variável de ambiente UserChoice. Isso resultaria no processamento do prompt duas vezes porque de "Y "não faz distinção entre maiúsculas e minúsculas "N"nem "Y"sem excluir primeiro todos os espaços. Portanto, UserChoicecom YSPACE como valor resultaria na execução do prompt uma segunda vez com a opção Ndefinida como padrão no arquivo em lote na segunda execução do prompt, que em seguida resulta em uma saída inesperada do processamento do arquivo em lote. Sim, uso seguro de SET / P é realmente complicado, não é?

Para obter ainda mais detalhes sobre o uso de SET / P e CHOICE para solicitar ao usuário uma escolha em uma lista de opções, consulte a resposta em Como impedir o interpretador de comandos do Windows de encerrar a execução do arquivo em lote com uma entrada incorreta do usuário?

Mais algumas dicas:

  1. IF compara as duas strings à esquerda e à direita do operador de comparação incluindo as aspas duplas. Então, case-insensitive comparação não é o valor de UserChoicecom Ne Y, mas o valor da UserChoicecercado por "com "N"e "Y".
  2. As IF operadores de comparação EQUe NEQsão projetados primário para comparação de dois números inteiros no intervalo de -2147483648 a 2147483647 e não para comparar duas cadeias. EQUe NEQfuncionam também para comparações de strings, mas resultam na comparação de strings entre aspas duplas em uma tentativa inútil de converter a string esquerda em um inteiro. EQUe NEQpode ser usado apenas com extensões de comando habilitadas. Os operadores de comparação para comparações de strings são ==e not ... ==que funcionam mesmo com extensões de comando desabilitadas, já que o command.comMS-DOS e o Windows 95/98 / ME já os suportam. Para obter mais detalhes sobre os operadores de comparação IF , consulte Símbolo equivalente a NEQ, LSS, GTR, etc. em arquivos em lote do Windows .
  3. O comando goto :EOFrequer extensões de comando ativadas para realmente sair do processamento do arquivo em lote. Para obter mais detalhes, consulte Para onde GOTO: EOF retorna?

Para entender os comandos usados ​​e como eles funcionam, abra uma janela de prompt de comando, execute lá os seguintes comandos e leia todas as páginas de ajuda exibidas para cada comando com muito cuidado.

  • choice /?
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?

Veja também:

Mofi
fonte
1
Esta é uma resposta incrível. De agora em diante, só usarei o Choice.exe.
Bas
choice.exe também existia no DOS desde 6.0
Brian Minton
@BrianMinton Isso não está certo. Estava disponível o aplicativo de 16 bits CHOICE.COMpor padrão no MS-DOS 6.0, MS-DOS 7.0, Windows 95 e Windows 98. Mas não havia nenhum choice.exeinstalado por padrão no Windows NT4, Windows 2000 e Windows XP. CHOICE.COMpode ser usado também no NT4, Windows 2000 e Windows XP, mas seria melhor usar 32 bits choice.exedo kit de recursos apropriado. Veja a página de Rob van der Woude sobre CHOICE . As opções são parcialmente diferentes entre CHOICE.COMe choice.exe. No entanto, a questão não é sobre o DOS.
Mofi
5

Aqui um pouco mais fácil:

@echo off
set /p var=Are You Sure?[Y/N]: 
if %var%== Y goto ...
if not %var%== Y exit

ou

@echo off
echo Are You Sure?[Y/N]
choice /c YN
if %errorlevel%==1 goto yes
if %errorlevel%==2 goto no
:yes
echo yes
goto :EOF
:no
echo no
Bob Smith
fonte
depois do Y coloque o comando que deseja que aconteça. É para isso que existem ... :)
Bob Smith
Eu quis dizer: %errorlevel%é sempre um valor inteiro. Veja aqui a documentação, incluindo um exemplo.
Stephan
1

Este é o meu método de referência para uma resposta sim / não .

Também não faz distinção entre maiúsculas e minúsculas.

Isso apenas verifica os erros fornecidos pela entrada e define a choicevariável para o que você precisar para que possa ser usada abaixo no código.

@echo off
choice /M "[Opt 1]  Do you want to continue [Yes/No]"
if errorlevel 255 (
  echo Error
  ) else if errorlevel 2 (
  set "YourChoice=will not"
  ) else if errorlevel 1 (
  set "YourChoice=will"
  ) else if errorlevel 0 (
  goto :EOF
  )
  echo %YourChoice%
  pause
Ste
fonte
0

Se você quiser que o programa em lote saia de volta para o prompt e não feche o prompt (também conhecido como cmd.exe), você pode usar "exit / b".

Isso pode ajudar.

set /p _sure="Are you sure?"
::The underscore is used to ensure that "sure" is not an enviroment
::varible
if /I NOT "_sure"=="y" (
::the /I makes it so you can
exit /b
) else (
::Any other modifications...
)

Ou se você não quiser usar tantas linhas ...

Set /p _sure="Are you sure?"
if /I NOT "_sure"=="y" exit /b
::Any other modifications and commands.

Espero que isto ajude...

Z. Mickaels
fonte
0

Aqui está um exemplo simples que uso em um script de backup (.bat / batch) no Windows 10, que me permite ter diferentes opções ao fazer backups.

...

:choice
set /P c=Do you want to rsync the archives to someHost[Y/N]?
if /I "%c%" EQU "Y" goto :syncthefiles
if /I "%c%" EQU "N" goto :doonotsyncthefiles
goto :choice

:syncthefiles
echo rsync files to somewhere ...
bash -c "rsync -vaz /mnt/d/Archive/Backup/ user@host:/home/user/Backup/blabla/"
echo done

:doonotsyncthefiles
echo Backup Complete!

...

Você pode ter quantos blocos precisar.


fonte
0

Primeiro, abra o terminal.

Então, digite

cd ~
touch .sure
chmod 700 .sure

A seguir, abra .sure e cole dentro.

#!/bin/bash --init-file
PS1='> '
alias y='
    $1
    exit
'
alias n='Taskkill /IM %Terminal% /f'
echo ''
echo 'Are you sure? Answer y or n.'
echo ''

Depois disso, feche o arquivo.

~/.sure ; ENTER COMMAND HERE

Isso lhe dará uma mensagem de tem certeza antes de continuar o comando.

user13636521
fonte
Talvez em bash, mas certamente não em lote.
Stephan
Oh. Eu acho que não. Funciona apenas para comandos de terminal, não para comandos em lote. Desculpe pela informação falsa.
user13636521
-1

Abra o terminal. Digite o seguinte

echo>sure.sh
chmod 700 sure.sh

Cole isso dentro de sure.sh

#!\bin\bash

echo -n 'Are you sure? [Y/n] '
read yn

if [ "$yn" = "n" ]; then
    exit 1
fi

exit 0

Feche sure.sh e digite isso no terminal.

alias sure='~/sure&&'

Agora, se você digitar sure antes de digitar o comando, será exibido um prompt de tem certeza antes de continuar o comando.

Espero que isso seja útil!

Contribuidor Anônimo
fonte
Talvez em bash, mas certamente não em lote.
Stephan