Como dormir em um arquivo em lotes?

132

Como pausar a execução por um tempo em um arquivo em lotes do Windows entre um comando e o próximo?

Massimo
fonte
Isso pretende se tornar um canônico? Nesse caso, algum texto explicativo pode ser apropriado.
John Gardeniers 26/09/12
2
"Texto explicativo" como em?
Massimo
2
A maioria, se não todas as perguntas canônicas que eu já vi, inclui texto descrevendo a intenção dessa pergunta.
John Gardeniers 27/09/12
Ou algum texto explicando a situação ... É principalmente para ajudar no SEO, mas também ajuda a estruturar respostas em potencial.
Chris S
2
SEO funcionando bem. Primeiro hit para mim na pesquisa do Google.
jbo5112

Respostas:

194

A maneira correta de dormir em um arquivo em lotes é usar o timeoutcomando, introduzido no Windows 2000.

Para esperar entre 29 e 30 segundos :

timeout /t 30

O tempo limite seria interrompido se o usuário pressionar qualquer tecla; no entanto, o comando também aceita a opção opcional /nobreak, que ignora efetivamente qualquer coisa que o usuário possa pressionar, exceto uma explícita CTRL-C:

timeout /t 30 /nobreak

Além disso, se você não quiser que o comando imprima sua contagem regressiva na tela, poderá redirecionar sua saída para NUL:

timeout /t 30 /nobreak > NUL
Massimo
fonte
6
O comando timeout não funciona com o Windows XP, mesmo com o kit de recursos 2003 instalado e o comando sleep não funciona no Windows 7, portanto, o comando ping ainda pode ser útil se você estiver usando o arquivo em lotes no Win7 e no WinXP.
12
timeout não funciona em scripts não interativos: "ERRO: O redirecionamento de entrada não é suportado, saindo do processo imediatamente." então, às vezes, usar o hack com "ping" é o preferido.
IMysak 26/10/2015
14

Como também se aplica aqui, copiarei minha resposta de outro site .

Se você deseja usar o ping, existe uma maneira melhor. Você deseja executar ping em um endereço que não existe, para poder especificar um tempo limite com precisão de milissegundos. Felizmente, esse endereço é definido em um padrão (RFC 3330), e é 192.0.2.x. Isso não é inventado, é realmente um endereço com o único objetivo de não existir (pode não estar claro, mas se aplica mesmo em redes locais):

192.0.2.0/24 - Este bloco é atribuído como "TEST-NET" para uso em documentação e código de exemplo. É frequentemente usado em conjunto com nomes de domínio example.com ou example.net na documentação de fornecedores e protocolos. Endereços dentro deste bloco não devem aparecer na Internet pública.

Para dormir por 123 milissegundos, use ping 192.0.2.1 -n 1 -w 123 >nul

mafu
fonte
3
Por favor, não faça isso, mesmo que seja um pouco melhor do que executar ping em um endereço real. Pingé simplesmente a ferramenta errada para o trabalho.
Massimo
1
@ Massimo Provavelmente não é o que se pretendia fazer :) Mas acho que ainda é uma boa solução - funciona melhor do que o tempo limite em alguns cenários (em particular, maior resolução). Além disso, tornou-se bastante conhecido, para que a maioria das pessoas não ficasse muito surpresa (ou seja, confusa) ao vê-lo no seu arquivo em lotes.
Mafu
2
@Massimo Alright! Acho que temos apenas opiniões diferentes. Se você não se importa, ainda vou deixar essa resposta, pois parece ser melhor do que executar ping localhost n vezes, como é descrito com mais frequência.
Mafu
7
timeout é a solução certa para os sistemas operacionais em que trabalha. ping é a única solução que funciona de 5.1-6.3. Com 25% dos sistemas ainda em 5.1, o tempo limite não é "a maneira correta".
Wyrmwood
3
timeout é a solução errada para qualquer sistema operacional, porque é fatalmente quebrado mesmo no Windows 10. Que uso é um comando que falha apenas porque a entrada é redirecionada?
Harry Johnston
8

Você também pode inserir um ping no host local. Isso levará 4 segundos para ser concluído (por padrão). É considerado um argumento por alguns, mas funciona muito bem da mesma forma.

O comando:
ping 127.0.0.1

acólito
fonte
6
Ehm ... todo o objetivo deste Q / A era exatamente corrigir duas outras perguntas que têm isso como resposta aceita, mas não podem mais ser corrigidas porque seu OP não existe mais.
Massimo
6
Embora funcione, é o equivalente a apertar um parafuso com um martelo. Uma ferramenta errada pode funcionar, mas ainda está errada.
precisa saber é o seguinte
1
@ MarkAllen Por outras palavras, Windows NT4, 95, 98, ME e versões mais antigas?
22412 Chris McKeown
5
@ MarkAllen - tecnicamente você precisa se preocupar se o pingseu sistema operacional vem ou não . Se você está preocupado o suficiente sobre '95 '98 ou ME, então você deve ser como igualmente preocupado com 6,22 que não tem pingtanto
Mark Henderson
4
@ MarkHenderson É mais fácil (para mim) lembrar se uma versão específica do sistema operacional suporta ou não o TCP / IP do que lembrar se inclui ou não um comando que eu não tinha ouvido anteriormente. Você sabe?
Mark Allen
2

Isenção de responsabilidade : esta não é a solução "ideal", então não se incomode em me bater na cabeça com isso, como feito para aqueles que recomendam ping...

Quando possível, use timeoutcom certeza. Mas, como observado nos comentários, isso nem sempre é uma opção (por exemplo, no modo não interativo). Depois disso, concordo que o ping"kludge" é talvez a próxima melhor opção, pois é muito simples. Dito isto, ofereço outra opção ... incorporar alguns scripts VB .

A base desta solução tem todos os tipos de aplicação além disso. Freqüentemente, o VBS pode fazer coisas que o lote não pode ou, pelo menos, fazê-lo com drasticamente mais facilidade. Usando a técnica ilustrada aqui, você pode misturar os dois (não "perfeitamente", mas "funcionalmente" ...).

Aqui está uma lista, para criar um script temporário, executá-lo e excluí-lo. O script dorme para você (por 3 segundos neste exemplo).

echo WScript.Sleep 3000 > %temp%\sleep.vbs & cscript %temp%\sleep.vbs %sleepMs% //B & del %temp%\sleep.vbs

Aqui está basicamente a mesma coisa, escrita de forma um pouco diferente:

set sleepMs=3000 & set sleepVbs=%temp%\sleep.vbs & echo WScript.Sleep WScript.Arguments(0) > %sleepVbs% & cscript %sleepVbs% %sleepMs% //B & del %sleepVbs%

E então, finalmente, como ping, CScriptem si tem uma opção de tempo limite! Portanto, se você inserir um loop infinito no script, poderá deixar o intérprete impor a duração. Observe que esta é uma operação "ocupada", que consome a CPU e, portanto, não a recomendo quando você pode usar o WScript.Sleepprocedimento, mas apresento como uma opção conceitual por uma questão de integridade:

set sleepSec=3 & set sleepVbs=%temp%\sleep.vbs & echo While True > %sleepVbs% & echo Wend >> %sleepVbs% & cscript %sleepVbs% //B //T:%sleepSec% & del %sleepVbs%
BuvinJ
fonte
Você sabe ... você poderia fazer isso no PowerShell, espero, sem ter que escrever um arquivo.
Harry Johnston
Sim, essa é provavelmente outra boa solução, embora essa seja mais compatível com versões anteriores do Windows.
BuvinJ 28/04