Comment dormir dans un fichier batch?

132

Comment suspendre temporairement l'exécution d'un fichier batch Windows entre une commande et la suivante?

Massimo
la source
Est-ce que cela est destiné à devenir canonique? Si c'est le cas, un texte explicatif pourrait être approprié.
John Gardeniers
2
"Texte explicatif" comme dans?
Massimo
2
La plupart des questions canoniques que j'ai vues, si ce n'est toutes, incluent un texte décrivant l'intention de cette question.
John Gardeniers
Ou un texte expliquant la situation ... Il s'agit principalement d'aider au référencement, mais aussi de cadrer les réponses potentielles.
Chris S
2
SEO fonctionne très bien. Premier coup pour moi sur la recherche Google.
jbo5112

Réponses:

194

La bonne façon de dormir dans un fichier de commandes consiste à utiliser la timeoutcommande introduite dans Windows 2000.

Pour attendre quelque part entre 29 et 30 secondes :

timeout /t 30

Le délai d'attente serait interrompu si l'utilisateur appuyait sur une touche quelconque. Cependant, la commande accepte également le commutateur optionnel /nobreak, qui ignore en réalité tout ce sur quoi l'utilisateur peut appuyer, à l'exception d'un explicite CTRL-C:

timeout /t 30 /nobreak

De plus, si vous ne souhaitez pas que la commande affiche son compte à rebours à l'écran, vous pouvez rediriger sa sortie vers NUL:

timeout /t 30 /nobreak > NUL
Massimo
la source
6
La commande timeout ne fonctionne pas avec Windows XP, même si le kit de ressources 2003 est installé et que la commande sleep ne fonctionne pas sous Windows 7; la commande ping peut donc toujours être utile si vous utilisez le fichier de commandes sous Win7 et WinXP.
12
timeout ne fonctionne pas dans les scripts non interactifs: "ERREUR: la redirection d'entrée n'est pas prise en charge, ce qui permet de quitter le processus immédiatement." donc parfois, utiliser hack avec "ping" est préférable.
iMysak
14

Comme cela s'applique ici aussi, je vais copier ma réponse depuis un autre site .

Si vous voulez utiliser ping, il existe un meilleur moyen. Vous voudrez envoyer une requête ping à une adresse inexistante afin de pouvoir spécifier un délai d'expiration avec une précision à la milliseconde. Heureusement, une telle adresse est définie dans une norme (RFC 3330), et elle l’est 192.0.2.x. Ce n'est pas inventé, c'est vraiment une adresse dont le seul but est de ne pas exister (ça peut ne pas être clair, mais ça s'applique même dans les réseaux locaux):

192.0.2.0/24 - Ce bloc est affecté à "TEST-NET" pour être utilisé dans la documentation et dans les exemples de code. Il est souvent utilisé avec les noms de domaine example.com ou example.net dans la documentation du fournisseur et du protocole. Les adresses de ce bloc ne doivent pas apparaître sur l'Internet public.

Pour dormir pendant 123 millisecondes, utilisez ping 192.0.2.1 -n 1 -w 123 >nul

mafu
la source
3
S'il vous plaît ne faites pas cela, même si c'est légèrement mieux que de cingler une vraie adresse. Pingest tout simplement le mauvais outil pour le travail.
Massimo
1
@ Massimo Ce n'est probablement pas ce que nous avions l'intention de faire :) Mais je pense que c'est quand même une bonne solution - cela fonctionne mieux que le timeout dans certains scénarios (en particulier une résolution plus élevée). En outre, il est devenu assez connu, de sorte que la plupart des gens ne seraient pas très surpris (confus) de le voir dans votre fichier de commandes.
Mafu
2
@ Massimo Très bien! Je suppose que nous avons juste des points de vue différents. Si vous le permettez, je vais quand même laisser cette réponse, car elle semble être préférable à envoyer un ping à l'hôte local n fois comme il est décrit le plus souvent.
Mafu
7
timeout est la bonne solution pour les systèmes d'exploitation sur lesquels il fonctionne. Le ping est la seule solution qui fonctionne à partir de 5.1-6.3. Avec 25% des systèmes encore sous 5.1, le délai d'attente n'est pas "dans le bon sens".
Wyrmwood
3
timeout est la mauvaise solution pour tous les systèmes d'exploitation, car il est fatalement cassé, même sous Windows 10. Quelle est l'utilisation d'une commande qui échoue simplement parce que l'entrée est redirigée?
Harry Johnston
8

Vous pouvez également insérer un ping à localhost. Cela prendra 4 secondes pour terminer (par défaut). Certains le considèrent comme un béguin, mais cela fonctionne quand même très bien.

La commande:
ping 127.0.0.1

acolyte
la source
6
Ehm ... le but de cette Q / A était exactement de corriger deux autres questions qui ont ceci comme réponse acceptée, mais ne peuvent plus être corrigées parce que leur PO n'est plus là.
Massimo
6
Bien que cela fonctionne, cela revient à enfoncer une vis avec un marteau. Un mauvais outil peut fonctionner, mais il est toujours faux.
voretaq7
1
@ MarkAllen En d'autres termes, Windows NT4, 95, 98, ME et plus ancien?
Chris McKeown
5
@MarkAllen - techniquement, vous devez alors vous demander si pingvotre système d'exploitation est fourni ou non . Si vous êtes assez inquiet pour '95 '98 ou ME, vous devriez être tout aussi inquiet pour 6.22 qui n'a pas non pingplus
Mark Henderson
4
@ MarkHenderson Il est plus facile (pour moi) de se rappeler si une version particulière du système d'exploitation prend en charge TCP / IP que de se rappeler si elle inclut ou non une commande que je n'avais pas entendue auparavant. Tu sais?
Mark Allen
2

Déni de responsabilité : ce n'est pas la solution "idéale", alors ne vous donnez pas la peine de me faire taper à la tête avec ça, comme c'est le cas pour ceux qui recommandent ping...

Si possible, utilisez timeoutà coup sûr. Mais comme indiqué dans les commentaires, ce n'est pas toujours une option (par exemple en mode non interactif). Après cela, je conviens que le ping"kludge" est peut-être la meilleure option, car il est très simple. Cela dit, je propose une autre option ... intégrer un script VB .

La base de cette solution a toutes sortes d’applications. Souvent, VBS peut faire des choses que le lot ne peut pas, ou du moins le faire avec beaucoup plus de facilité. En utilisant la technique illustrée ici, vous pouvez mélanger les deux (pas "de manière transparente", mais "de manière fonctionnelle" ...).

Voici un one-line pour créer un script temporaire, l'exécuter, puis le supprimer. Le script veille pour vous (pendant 3 secondes dans cet exemple).

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

Voici fondamentalement la même chose, écrite un peu différemment:

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

Et puis finalement, comme ping, a CScriptlui - même une option de délai d'attente! Ainsi, si vous entrez une boucle infinie dans le script, vous pouvez laisser l'interprète appliquer la durée. Notez que ceci est une opération "occupée", qui consomme le processeur, et par conséquent, je ne le recommande pas lorsque vous pouvez utiliser la WScript.Sleepprocédure, mais je le présente comme une option conceptuelle par souci d'exhaustivité:

set sleepSec=3 & set sleepVbs=%temp%\sleep.vbs & echo While True > %sleepVbs% & echo Wend >> %sleepVbs% & cscript %sleepVbs% //B //T:%sleepSec% & del %sleepVbs%
BuvinJ
la source
Vous savez ... vous pouvez le faire dans PowerShell, je suppose, sans avoir à écrire de fichier.
Harry Johnston
Oui, c'est probablement une autre bonne solution, même si celle-ci est plus compatible avec les anciennes versions de Windows.
BuvinJ