Dormindo em um arquivo em lotes

151

Ao escrever um arquivo em lotes para automatizar algo em uma caixa do Windows, precisei interromper sua execução por alguns segundos (geralmente em um loop de teste / espera, aguardando o início do processo). Naquela época, a melhor solução que eu encontrava usa o ping (não é brincadeira) para obter o efeito desejado. Encontrei uma descrição melhor aqui , que descreve um "wait.bat" exigível, implementado da seguinte maneira:

@ping 127.0.0.1 -n 2 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul

Você pode incluir chamadas para wait.bat em seu próprio arquivo em lotes, passando o número de segundos para dormir.

Aparentemente, o Windows 2003 Resource Kit fornece um comando de suspensão semelhante ao Unix (finalmente!). Enquanto isso, para aqueles que ainda usam o Windows XP, Windows 2000 ou (infelizmente) o Windows NT , existe uma maneira melhor?

Modifiquei o sleep.pyscript na resposta aceita , para que o padrão seja um segundo se nenhum argumento for passado na linha de comando:

import time, sys

time.sleep(float(sys.argv[1]) if len(sys.argv) > 1 else 1)
Jason Etheridge
fonte
A página de download da Microsoft do Windows 2003 Resource Kit indica que também funciona para o XP. Receio que não haja outra opção a não ser usar um utilitário 'externo' para fazer a espera: não há nada como isso embutido no processador de comando do XP.
GerG 03/10/08
O kit de recursos Server 2003 funciona com o Windows XP (e provavelmente com w2k)
Martin Beckett
Eu enfrentei o mesmo problema no passado e usei ping sozinho (com uma observação acima documentando claramente que eu percebo que isso é estúpido :)).
21330 Jack Leow
2
Você tem algumas opções - emule uma suspensão com o pingcomando ou faça o download do kit de recursos do Windows, que inclui um sleepcomando. Mais detalhes aqui: Arquivo em lote SLEEP Command
Rudu 25/03

Respostas:

14

ATUALIZAR

O timeoutcomando, disponível no Windows Vista e em diante, deve ser o comando usado, conforme descrito em outra resposta a esta pergunta. O que se segue aqui é um antigo resposta .

Resposta antiga

Se você tem o Python instalado ou não se importa de instalá-lo (ele também tem outros usos :), basta criar o seguinte script sleep.py e adicioná-lo em algum lugar no seu PATH:

import time, sys

time.sleep(float(sys.argv[1]))

Isso permitirá pausas de segundos (por exemplo, 1,5 segundos, 0,1 etc.), caso você precise. Se você quiser chamá-lo como sleeppreferir sleep.py, pode adicionar a .PYextensão à sua variável de ambiente PATHEXT. No Windows XP, você pode editá-lo em:

Meu computador → Propriedades (menu) → Avançado (guia) → Variáveis ​​de ambiente (botão) → Variáveis ​​do sistema (quadro)

tzot
fonte
32
por que devemos escrever um script em python quando a solução com script em lote é solicitada? Como a extensão de caminho pode resolver o problema de que os usuários do Windows não têm intérprete de python instalado? Obrigado.
Val
6
Por uma questão de portabilidade, acho que essa solução deve ser evitada, pois existem alternativas nativas perfeitamente perfeitas.
Gras Double
1
Essa abordagem pode ter fornecido uma solução alternativa no passado, mas a solução nativa descrita por @Blorgbeard é definitivamente o caminho a percorrer.
Mike
227

O timeoutcomando está disponível no Windows Vista em diante:

c:\> timeout /?

TIMEOUT [/T] timeout [/NOBREAK]

Description:
    This utility accepts a timeout parameter to wait for the specified
    time period (in seconds) or until any key is pressed. It also
    accepts a parameter to ignore the key press.

Parameter List:
    /T        timeout       Specifies the number of seconds to wait.
                            Valid range is -1 to 99999 seconds.

    /NOBREAK                Ignore key presses and wait specified time.

    /?                      Displays this help message.

NOTE: A timeout value of -1 means to wait indefinitely for a key press.

Examples:
    TIMEOUT /?
    TIMEOUT /T 10
    TIMEOUT /T 300 /NOBREAK
    TIMEOUT /T -1

Nota: Ele não funciona com o redirecionamento de entrada - exemplo trivial:

C:\>echo 1 | timeout /t 1 /nobreak
ERROR: Input redirection is not supported, exiting the process immediately.
Blorgbeard está fora
fonte
8
não funciona em usos sem console: "ERRO: O redirecionamento de entrada não é suportado, saindo do processo imediatamente."
simpleuser
Eu quis dizer casos em que você não tem um console em tudo, como quando o arquivo de lote é executado em segundo plano através de um garfo de algum outro processo, um crontab cygwin, ou comando ssh remoto, etc.
simpleuser
1
Oh sim, eu sei. O exemplo que dei foi apenas para demonstrar o erro :)
Blorgbeard está fora de 30/08/2013
3
O link para a documentação timeout, adicionado por @Cristian Ciupitu, está parcialmente errado - o Windows XP não possui esse comando.
martineau
1
@ HelloWorld que parece um problema com o seu% PATH%
Blorgbeard saiu
21

Usando o ping método descrito é como o faço quando não posso (ou não quero) adicionar mais executáveis ​​ou instalar qualquer outro software.

Você deve executar ping em algo que não existe, e usar o -wsinalizador para que ele falhe após esse período de tempo, não em executar ping em algo que esteja lá (como localhost)-n . Isso permite que você lide com o tempo em menos de um segundo, e acho que é um pouco mais preciso.

por exemplo

(teste que 1.1.1.1 não foi realizado)

ECHO Waiting 15 seconds

PING 1.1.1.1 -n 1 -w 15000 > NUL
  or
PING -n 15 -w 1000 127.1 >NUL
daniel
fonte
Instantaneamente retorna comPING: transmit failed. General failure.
huysentruitw 28/05
O IP 1.1.1.1é obtido pelo CloudFlare, portanto, isso não espera 15s, mas cerca de alguns ms.
dhcgn
16

SLEEP.exeestá incluído na maioria dos kits de recursos, por exemplo, o Windows Server 2003 Resource Kit, que também pode ser instalado no Windows XP.

Usage:  sleep      time-to-sleep-in-seconds
        sleep [-m] time-to-sleep-in-milliseconds
        sleep [-c] commited-memory ratio (1%-100%)
Luk
fonte
15

Discordo das respostas que encontrei aqui.

Eu uso o seguinte método inteiramente baseado nos recursos do Windows XP para atrasar um arquivo em lotes:

DELAY.BAT:

@ECHO OFF
REM DELAY seconds

REM GET ENDING SECOND
FOR /F "TOKENS=1-3 DELIMS=:." %%A IN ("%TIME%") DO SET /A H=%%A, M=1%%B%%100, S=1%%C%%100, ENDING=(H*60+M)*60+S+%1

REM WAIT FOR SUCH A SECOND
:WAIT
FOR /F "TOKENS=1-3 DELIMS=:." %%A IN ("%TIME%") DO SET /A H=%%A, M=1%%B%%100, S=1%%C%%100, CURRENT=(H*60+M)*60+S
IF %CURRENT% LSS %ENDING% GOTO WAIT

Você também pode inserir o dia no cálculo para que o método também funcione quando o intervalo de atraso passar à meia-noite.

Aacini
fonte
15
Isso deve ser preciso, mas é uma maneira intensiva de CPU. Normalmente, você deseja uma implementação orientada a interrupções para que o processo não consuma ciclos da CPU enquanto aguarda. Isso não deve ser um problema para esperas curtas e pouco frequentes, como provavelmente é o caso da maioria das situações em lote. Mas um processo em execução contínua com longas esperas pode ter um impacto negativo no desempenho do sistema.
dbenham
4
Como ele usa o relógio do sistema, a precisão é de um segundo. Se 2 segundos for especificado, o atraso poderá ser entre 2 segundos e 3 segundos (atualmente 2,99999 ... segundos).
Peter Mortensen
E se a hora for agora 7:59:59 e você quiser esperar 7 segundos? Parece que não leva isso em consideração.
ashes999
Isso consome mais tempo da CPU do que o tempo do sistema. Além disso, você está executando operações aritméticas com números octais, pois minutos e segundos menores que 10 são exibidos com um 0 à esquerda no TIMEcomando.
Andreas
2
@ MRT: O problema é que você %TIME%usa uma vírgula para separar os centisegundos, em vez de um ponto! Basta adicionar uma vírgula no DELIMS=:.,"...
Aacini
13

Eu enfrentei um problema semelhante, mas acabei de ligar um aplicativo de console C ++ muito curto para fazer a mesma coisa. Basta executar o MySleep.exe 1000 - talvez mais fácil do que baixar / instalar todo o kit de recursos.

#include <tchar.h>
#include <stdio.h>
#include "Windows.h"

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc == 2)
    {
        _tprintf(_T("Sleeping for %s ms\n"), argv[1]);
        Sleep(_tstoi(argv[1]));
    }
    else
    {
        _tprintf(_T("Wrong number of arguments.\n"));
    }
    return 0;
}
John Sibly
fonte
10

Na falha do servidor, uma pergunta semelhante foi feita e a solução foi:

choice /d y /t 5 > nul
mlsteeves
fonte
7
FYI: A escolha não está incluída no Windows XP. Estava no Windows 9x, removido do XP e adicionado novamente para o Vista em diante.
Devin Burke
7
Eu não recomendo isso. Pelo menos em todas as CHOICEversões que eu conheço, se alguém pressiona um botão enquanto espera, o que pessoas impacientes às vezes fazem, então a opção registra uma entrada, emite um sinal sonoro ao sistema por uma entrada incorreta e interrompe o temporizador, o que significa que ele travará lá, a menos que eles pressionem N ou Y. E se eles pressionarem um desses dois, então a escolha será encerrada em vez de esperar pelo 5. Além disso, essa opção está usando uma sintaxe do Vista realmente estranha. Todos os comandos de escolha normal seriam usados CHOICE /T:Y,5 > NULpara isso. Não há /Dsinalizador nas versões antigas.
Codificando com estilo
1
Para completar, pelo menos os comandos CHOICE que eu conheço têm botões padrão sim / não diferentes, com base no idioma em que ele veio, portanto, se você confiar em uma opção [Y, N] padrão, em vez de especificá-lo explicitamente com /C:YNou apenas /C:Y, isso não funcionará quando alguém tiver, digamos, um comando de escolha sueco que provavelmente fará um [J, N] por padrão. Portanto, isso está atolado em todos os tipos de problemas.
Codificando com estilo
1
@Coding Testou isso no Win7 e, se o usuário pressionar um botão, ele emitirá um sinal sonoro; no entanto, o tempo limite será excedido após 5 segundos adicionais após o usuário pressionar um botão. Portanto, se o usuário continuar pressionando as teclas, o tempo limite nunca será excedido. Além disso, no meu caso, quando usei isso, acredito que oculte o console, para que o usuário não possa pressionar o botão. Nesse sistema, não havia acesso ao Python, não havia acesso para eliminar meu próprio exe no sistema (como sugerido em algumas outras respostas), eu era bastante limitado no que podia fazer. Então, o que você recomendaria?
mlsteeves
@mlsteeves Cada Windows, DOS, etc. diferente tem um comando de escolha diferente e, como observado, normalmente não está disponível no Xp. Muitos comandos de escolha têm um comportamento sutilmente diferente e alguns até têm sintaxe diferente. Eu, geralmente uso o comando ping quando preciso dormir. É feio, mas confiável.
Codificando com estilo
9

Você pode usar a camada WSH cscript do Windows e esse arquivo JavaScript wait.js :

if (WScript.Arguments.Count() == 1)
    WScript.Sleep(WScript.Arguments(0)*1000);
else
    WScript.Echo("Usage: cscript wait.js seconds");
Blake7
fonte
1
O host de scripts do Windows pode ser desativado por meio de diretivas de grupo.
Joey #
8

Dependendo das suas necessidades de compatibilidade, use ping:

ping -n <numberofseconds+1> localhost >nul 2>&1

por exemplo, para esperar 5 segundos, use

ping -n 6 localhost >nul 2>&1

ou no Windows 7 ou posterior, use timeout:

timeout 6 >nul
Joey
fonte
2
-westá em milissegundos, -né apenas o número de vezes que o ping é efetuado e o tempo padrão entre pings é um segundo.
Joey
8

Você pode usar o ping:

ping 127.0.0.1 -n 11 -w 1000 >nul: 2>nul:

Esperará 10 segundos.

O motivo pelo qual você deve usar o 11 é porque o primeiro ping sai imediatamente, não depois de um segundo. O número deve sempre ser um a mais que o número de segundos que você deseja esperar.

Lembre-se de que o objetivo -wnão é esperar um segundo. É para garantir que você não espere mais de um segundo, caso haja problemas de rede. pingpor si só enviará um pacote ICMP por segundo. Provavelmente não é necessário para o host local, mas os velhos hábitos são difíceis.

paxdiablo
fonte
não é recomendável usá-lo para processamento crítico em tempo real. porque comando PING está sendo usado, é possível que este arquivo de lote de espera pode executar mais de alguns milissegundos
Wael Dalloul
12
@ Wael, se você está falando em esperar nos limites de um segundo, alguns milissegundos serão irrelevantes. E se você estiver usando o cmd.exe para obter informações em tempo real, você merece tudo o que obtém :-) #
386
-w é um valor de tempo limite. É o número de milissegundos de espera por uma resposta ... não a quantidade de tempo de espera entre pings.
quux
@quux, em nenhum lugar eu indiquei -wo tempo limite (embora eu admita que alguns possam inferir que devido à minha falta de clareza), ele é realmente usado para limitar o tempo do ciclo em que existem problemas de rede que causariam cada ciclo mais do que o alocado segundo. Adicionei um parágrafo ao final para esclarecer isso.
28411
O problema é que, se os pings retornarem mais rapidamente , não espere um segundo inteiro entre os pings. por isso sua espera ciclo vai terminar mais rápido do que você pensou que seria
quux
7

Existe uma maneira melhor de dormir usando o ping. 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
Sim, é mais fácil escrever e entender do que adicionar um ao -nparâmetro.
31516 Peter Mortensen
No entanto, eu o medi (usando 100 pings). Se eu usar -n 3 -w 124, o tempo real é exatamente (3 + 1) * (124 + 1) = 4 * 125 = 500 ms. O tempo é surpreendentemente estável, exato à resolução de 10 ms na leitura (por um prompt do CMD com o tempo) - e a resolução subjacente é definitivamente melhor que 10 ms (não afetada pela resolução normal de tick de 16 ms).
22416 Peter Mortensen
@mafu O fato de que 192.0.2.0/24 não deve ser usado não significa que não pode ser usado e, portanto, não há garantia de que não haja resposta nas solicitações de eco. Por exemplo, configure para qualquer PC com Windows o endereço IPv4 estático 192.0.2.1 e a máscara de sub-rede 255.255.255.0 e conecte o adaptador de rede a qualquer outro dispositivo. Basta um simples interruptor no qual nada mais está conectado. Em seguida, execute ping 192.0.2.1este PC com Windows e é possível ver que a pilha TCP / IP do Windows responde às solicitações de eco. Quantas pessoas sabem que 192.0.2.0/24 não deve ser usado para um endereço IPv4 estático?
Mofi
1
Pela discussão nos comentários aqui , parece que 192.0.2.1 não é tão infalível e alguns sugerem que 127.255.255.255 é uma escolha melhor. Pensamentos?
JLRishe
Os comentários mencionados no post acima já foram removidos (provavelmente como NLN), mas eu concordo com a mudança 127.255.255.255, devido ao facto de ser um endereço de broadcast loopback no Windows que já foi atribuído a por padrão (Você pode confirmar isso executando route printem cmd e olhando através da tabela de rotas IPv4 impressa).
Hoppeduppeanut
6

Se você possui o PowerShell em seu sistema, basta executar este comando:

powershell -command "Start-Sleep -s 1"

Edit: da minha resposta em um tópico semelhante , as pessoas levantaram um problema em que a quantidade de tempo que o PowerShell leva para iniciar é significativa em comparação com o tempo que você está tentando esperar. Se a precisão do tempo de espera for importante (isto é, um atraso extra de um ou dois segundos não é aceitável), você pode usar esta abordagem:

powershell -command "$sleepUntil = [DateTime]::Parse('%date% %time%').AddSeconds(5); $sleepDuration = $sleepUntil.Subtract((get-date)).TotalMilliseconds; start-sleep -m $sleepDuration"

Isso leva o tempo em que o comando windows foi emitido e o script do PowerShell dorme até 5 segundos após esse horário. Portanto, desde que o PowerShell leve menos tempo para iniciar do que a duração do sono, essa abordagem funcionará (são cerca de 600ms na minha máquina).

Niall Connaughton
fonte
6
timeout /t <seconds> <options>

Por exemplo, para fazer com que o script execute uma espera ininterrupta de 2 segundos:

timeout /t 2 /nobreak >NUL

O que significa que o script aguardará 2 segundos antes de continuar.

Por padrão, um pressionamento de tecla interrompe o tempo limite; portanto, use a /nobreakopção se você não quiser que o usuário possa interromper (cancelar) a espera. Além disso, o tempo limite fornecerá notificações por segundo para notificar o usuário quanto tempo resta a esperar; isso pode ser removido direcionando o comando para NUL.

edit: como o @martineau aponta nos comentários , o timeoutcomando está disponível apenas no Windows 7 e superior. Além disso, o pingcomando usa menos tempo do processador que timeout. Ainda acredito em usar sempre timeoutque possível, pois é mais legível que o ping'hack'. Leia mais aqui .

mgthomas99
fonte
2
Aparentemente, este comando está disponível apenas no Windows 7/2008 e no XP Resource Kit (e possivelmente 8 / 8.1). A fonte também afirma que a pingabordagem usa menos tempo do processador.
amigos estão dizendo sobre martineau
5

Basta colocar isso no seu arquivo em lotes onde você deseja a espera.

@ping 127.0.0.1 -n 11 -w 1000 > null
Brent Stewart
fonte
Como isso difere da resposta de paxdiablo?
Peter Mortensen
2
Não é diferente, mas as respostas aqui são de várias perguntas mescladas, portanto nem todas as respostas existiram quando eu respondi.
Brent Stewart
4

No bloco de notas, escreva:

@echo off
set /a WAITTIME=%1+1
PING 127.0.0.1 -n %WAITTIME% > nul
goto:eof

Agora salve como wait.bat na pasta C: \ WINDOWS \ System32 e, sempre que desejar, use:

CALL WAIT.bat <whole number of seconds without quotes>
SuperKael
fonte
Ele se pinga repetidamente, aguardando um segundo entre cada ping e, em seguida, retorna ao programa de chamada, não vejo o loop infinito, mas eu mesmo o testei.
SuperKael
Meu erro, não há loop infinito. No entanto, como mencionado em uma das outras respostas , é melhor pingusar algo não apenas uma vez e usar a -w Timeoutopção de atraso em milissegundos em vez da opção de -n Countnúmero de tentativas inteiras.
martineau
-w Timeoutpode ser melhor, mas verifiquei que ele pingava mais uma vez que o tempo digitado.
SuperKael
4

O Resource Kit sempre incluiu isso. Pelo menos desde o Windows 2000.

Além disso, o pacote Cygwin tem um sleepplugin para o seu PATH e inclui o cygwin.dll(ou como é chamado) e o caminho a seguir!

Daren Thomas
fonte
2
Observe que o cygwin1.dll não coexiste pacificamente com diferentes versões de si mesmo. É melhor você ter um e apenas um cygwin1.dll em sua máquina ou obterá falhas estranhas.
JesperE
Qual Kit de Recursos? Parece haver mais de um. Você pode atualizar sua resposta?
Peter Mortensen
3

Eu gosto da resposta de Aacini . Eu adicionei a ele para lidar com o dia e também para lidar com centisegundos ( %TIME%saídas H:MM:SS.CC):

:delay
SET DELAYINPUT=%1
SET /A DAYS=DELAYINPUT/8640000
SET /A DELAYINPUT=DELAYINPUT-(DAYS*864000)

::Get ending centisecond (10 milliseconds)
FOR /F "tokens=1-4 delims=:." %%A IN ("%TIME%") DO SET /A H=%%A, M=1%%B%%100, S=1%%C%%100, X=1%%D%%100, ENDING=((H*60+M)*60+S)*100+X+DELAYINPUT
SET /A DAYS=DAYS+ENDING/8640000
SET /A ENDING=ENDING-(DAYS*864000)

::Wait for such a centisecond
:delay_wait
FOR /F "tokens=1-4 delims=:." %%A IN ("%TIME%") DO SET /A H=%%A, M=1%%B%%100, S=1%%C%%100, X=1%%D%%100, CURRENT=((H*60+M)*60+S)*100+X
IF DEFINED LASTCURRENT IF %CURRENT% LSS %LASTCURRENT% SET /A DAYS=DAYS-1
SET LASTCURRENT=%CURRENT%
IF %CURRENT% LSS %ENDING% GOTO delay_wait
IF %DAYS% GTR 0 GOTO delay_wait
GOTO :EOF
Hossy
fonte
3

Eu tenho usado este programa de suspensão c #. Pode ser mais conveniente para você se C # é o seu idioma preferido:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace sleep
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 1)
            {
                double time = Double.Parse(args[0]);
                Thread.Sleep((int)(time*1000));
            }
            else
            {
                Console.WriteLine("Usage: sleep <seconds>\nExample: sleep 10");
            }
        }
    }
}
Liam
fonte
3

Ainda mais leve que a solução Python é o linux Perl.

Para dormir por sete segundos, coloque isso no script BAT:

perl -e "sleep 7"

Esta solução fornece apenas uma resolução de um segundo.

Se você precisar de uma resolução mais alta, use o módulo Time :: HiRes do CPAN. Ele fornece usleep()qual dorme em microssegundos e nanosleep()qual dorme em nanossegundos (ambas as funções usam apenas argumentos inteiros). Consulte a pergunta Estouro de pilha Como durmo um milissegundo em Perl? para mais detalhes.

Eu tenho usado o ActivePerl por muitos anos. É muito fácil de instalar.

Peter Mortensen
fonte
2

Ou na linha de comando Python, por exemplo, por 6 segundos e meio:

python -c "import time;time.sleep(6.5)"
Alex Robinson
fonte
Embora mais curta, essa é uma duplicata da resposta aceita.
Peter Mortensen
@ Peter Mortensen: Ele também permite que você coloque facilmente tudo em uma única linha de um arquivo em lotes.
27612 martineau
2

O uso do ping é bom, desde que você queira "esperar um pouco". Isso porque você depende de outras funções abaixo, como sua rede funcionando e o fato de que não há nada respondendo no 127.0.0.1. ;-) Talvez não seja muito provável que falhe, mas não é impossível ...

Se você quiser ter certeza de que está esperando exatamente o tempo especificado, use o sleep funcionalidade (que também tem a vantagem de não usar a energia da CPU ou esperar que a rede esteja pronta).

Encontrar um executável já feito para dormir é a maneira mais conveniente. Basta soltá-lo na pasta do Windows ou em qualquer outra parte do caminho padrão e ele estará sempre disponível.

Caso contrário, se você tiver um ambiente de compilação, poderá criar um. A Sleepfunção está disponível em kernel32.dll, então você só precisa usá-la. :-) Para VB / VBA, declare o seguinte no início de sua fonte para declarar uma função de suspensão:

private Declare Sub Sleep Lib "kernel32" Alias "Sleep" (byval dwMilliseconds as Long)

Para C #:

[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);

Você encontrará aqui mais sobre esta funcionalidade (disponível desde o Windows 2000) na função Sleep (MSDN).

No padrão C, sleep()está incluído na biblioteca padrão e no Visual Studio C da Microsoft, a função é nomeada Sleep(), se a memória me servir. ;-) Esses dois aceitam o argumento em segundos, não em milissegundos, como as duas declarações anteriores.

Tooony
fonte
1
O sono está disponível na estrutura .net - veja a classe de threads, por exemplo: using System.Threading; .... Thread.Sleep (1000);
John Sibly 03/10/08
2
Se o "ping 127.0.0.1" falhar, você precisará se preocupar com coisas mais sérias do que "sleep" - esta é a interface de loopback, qualquer coisa que o RPC provavelmente enlouquecer.
Piskvor saiu de prédio 04/04/2009
2

A melhor solução que deve funcionar em todas as versões do Windows após o Windows 2000 seria:

timeout numbersofseconds /nobreak > nul
Tato
fonte
Não funciona no XP Pro ...'timeout' is not recognized as an internal or external command, operable program or batch file.
martineau 29/03
1

O pathping.exe pode dormir menos de um segundo.

@echo off
setlocal EnableDelayedExpansion 
echo !TIME! & pathping localhost -n -q 1 -p %~1 2>&1 > nul & echo !TIME!

.

> sleep 10
17:01:33,57
17:01:33,60

> sleep 20
17:03:56,54
17:03:56,58

> sleep 50
17:04:30,80
17:04:30,87

> sleep 100
17:07:06,12
17:07:06,25

> sleep 200
17:07:08,42
17:07:08,64

> sleep 500
17:07:11,05
17:07:11,57

> sleep 800
17:07:18,98
17:07:19,81

> sleep 1000
17:07:22,61
17:07:23,62

> sleep 1500
17:07:27,55
17:07:29,06
Andry
fonte
1

Estou impressionado com este:

http://www.computerhope.com/batch.htm#02

choice /n /c y /d y /t 5 > NUL

Tecnicamente, você está dizendo ao choicecomando para aceitar apenas y. O padrão é y, fazê-lo em 5 segundos, não chamar nenhum prompt e despejar tudo o que diz para NUL (como terminal nulo no Linux).

Chris Moschini
fonte
3
Vou me ecoar aqui: não recomendo nada. Nas CHOICEversões que eu conheço, se alguém pressiona uma tecla enquanto aguarda, o que pessoas impacientes fazem às vezes, então a escolha lê uma entrada, emite um sinal sonoro para uma entrada incorreta e interrompe a contagem regressiva, para que ela seja interrompida, a menos que pressione Y. E se eles simplesmente apertarem Y, então a escolha termina aí, em vez de esperar pelo 5. Além disso, essa opção está usando uma sintaxe do Vista realmente estranha. Os comandos de escolha normal são usados CHOICE /T:Y,5 > NULpara isso. (Não há sinalizador / D nas versões antigas.) E se você possui o Vista, use-o TIMEOUT.
Codificando com estilo
1

Você também pode usar um arquivo .vbs para executar tempos limite específicos:

O código abaixo cria o arquivo .vbs. Coloque isso perto do topo do seu código rbatch:

echo WScript.sleep WScript.Arguments(0) >"%cd%\sleeper.vbs"

O código abaixo abre o arquivo .vbs e especifica quanto tempo esperar:

start /WAIT "" "%cd%\sleeper.vbs" "1000"

No código acima, "1000" é o valor do atraso a ser enviado ao arquivo .vbs em milissegundos, por exemplo, 1000 ms = 1 s. Você pode alterar esta parte para o tempo que desejar.

O código abaixo exclui o arquivo .vbs após o término. Coloque isso no final do seu arquivo em lotes:

del /f /q "%cd%\sleeper.vbs"

E aqui está o código todo, portanto, é fácil copiar:

echo WScript.sleep WScript.Arguments(0) >"%cd%\sleeper.vbs"
start /WAIT "" "%cd%\sleeper.vbs" "1000"
del /f /q "%cd%\sleeper.vbs"
ÉpicoNinjaQueijo
fonte
1

No Windows Vista, você possui os comandos TIMEOUT e SLEEP , mas para usá-los no Windows XP ou no Windows Server 2003, você precisará do kit de ferramentas de recursos do Windows Server 2003 .

Aqui você tem uma boa visão geral das alternativas de suspensão (a abordagem ping é a mais popular, pois funcionará em todas as máquinas Windows), mas há (pelo menos) uma não mencionada que (ab) usa o W32TMcomando (Time Service):

w32tm /stripchart /computer:localhost /period:1 /dataonly /samples:N  >nul 2>&1

Onde você deve substituir o N pelos segundos que deseja pausar. Além disso, ele funcionará em todos os sistemas Windows sem pré-requisitos.

Typeperf também pode ser usado:

typeperf "\System\Processor Queue Length" -si N -sc 1 >nul

Com mshta e javascript (pode ser usado para dormir em menos de um segundo):

start "" /wait /min /realtime mshta "javascript:setTimeout(function(){close();},5000)"

Isso deve ser ainda mais preciso (por aguardar menos de um segundo) - executável auto-compilável com base em .net:

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal
::del %~n0.exe /q /f
::
:: For precision better call this like
:: call waitMS 500
:: in order to skip compilation in case there's already built .exe
:: as without pointed extension first the .exe will be called due to the ordering in PATEXT variable
::
::
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /w:0 /out:"%~n0.exe" "%~dpsfnx0"
)


%~n0.exe %*

endlocal & exit /b %errorlevel%


*/


import System;
import System.Threading;

var arguments:String[] = Environment.GetCommandLineArgs();
function printHelp(){
    Console.WriteLine(arguments[0]+" N");
    Console.WriteLine(" N - milliseconds to wait");
    Environment.Exit(0);    
}

if(arguments.length<2){
    printHelp();
}

try{
    var wait:Int32=Int32.Parse(arguments[1]);
    System.Threading.Thread.Sleep(wait);
}catch(err){
    Console.WriteLine('Invalid Number passed');
    Environment.Exit(1);
}
npocmaka
fonte
1

Existem várias maneiras de realizar um ' sono ' ' em cmd / lote:

Meu favorito:

TIMEOUT /NOBREAK 5 >NUL 2>NUL

Isso interromperá o console por 5 segundos, sem nenhuma saída.

Mais usado:

ping localhost -n 5 >NUL 2>NUL

Isso tentará fazer uma conexão localhost5 vezes. Como ele está hospedado no seu computador, ele sempre alcançará o host; portanto, a cada segundo, ele tentará o novo a cada segundo. O -nsinalizador indica quantas vezes o script tentará a conexão. Nesse caso, é 5, portanto, durará 5 segundos.

Variantes do último:

ping 1.1.1.1 -n 5 >nul

Neste script, existem algumas diferenças comparando-o com o último. Isso não tentará ligar localhost. Em vez disso, ele tentará se conectar a 1.1.1.1um site muito rápido. A ação durará 5 segundos apenas se você tiver uma conexão ativa com a Internet. Caso contrário, durará aproximadamente 15 para concluir a ação . Eu não recomendo usar este método.

ping 127.0.0.1 -n 5 >nul

É exatamente igual ao exemplo 2 (mais usado). Além disso, você também pode usar:

ping [::1] -n 5 >nul

Em vez disso, usa a localhostversão do IPv6 .

Existem muitos métodos para executar esta ação. No entanto, prefiro o método 1 para Windows Vista e versões posteriores e o método mais usado (método 2) para versões anteriores do sistema operacional.

Lumito
fonte
0

Você pode se interessar colocando a mensagem PAUSE na barra de título:

@ECHO off
SET TITLETEXT=Sleep
TITLE %TITLETEXT%
CALL :sleep 5
GOTO :END
:: Function Section
:sleep ARG
ECHO Pausing...
FOR /l %%a in (%~1,-1,1) DO (TITLE Script %TITLETEXT% -- time left^
 %%as&PING.exe -n 2 -w 1000 127.1>NUL)
EXIT /B 0
:: End of script
:END
pause
::this is EOF
djangofan
fonte
0

Isso foi testado no Windows XP SP3 e Windows 7 e usa CScript. Coloquei alguns guardas seguros para evitar del "" avisos. ( /qseria perigoso)

Espere um segundo:

sleepOrDelayExecution 1000

Aguarde 500 ms e execute as coisas depois de:

sleepOrDelayExecution 500 dir \ /s

sleepOrDelayExecution.bat:

@echo off
if "%1" == "" goto end
if NOT %1 GTR 0 goto end
setlocal
set sleepfn="%temp%\sleep%random%.vbs"
echo WScript.Sleep(%1) >%sleepfn%
if NOT %sleepfn% == "" if NOT EXIST %sleepfn% goto end
cscript %sleepfn% >nul
if NOT %sleepfn% == "" if EXIST %sleepfn% del %sleepfn%
for /f "usebackq tokens=1*" %%i in (`echo %*`) DO @ set params=%%j
%params%
:end
Covarde anônimo
fonte
0

Como outros sugerem programas de terceiros (Python, Perl, aplicativo personalizado etc.), outra opção é o GNU CoreUtils for Windows, disponível em http://gnuwin32.sourceforge.net/packages/coreutils.htm .

2 opções para implantação:

  1. Instale o pacote completo (que incluirá o conjunto completo de CoreUtils, dependências, documentação, etc.).
  2. Instale apenas as dependências binárias e necessárias 'sleep.exe' (use depends.exe para obter dependências).

Um benefício da implantação do CoreUtils é que você também receberá uma série de outros programas úteis para scripts (o lote do Windows deixa muito a desejar).

codesniffer
fonte