Exécution de commandes de fichier de commandes Windows de manière asynchrone

187

Dis, si j'ai

  • foo.exe
  • bar.exe
  • baz.exe

Comment les exécuter tous à partir d'un fichier batch de manière asynchrone, c'est-à-dire sans attendre l'arrêt du programme précédent?

RichN
la source

Réponses:

254

L'utilisation de la STARTcommande pour exécuter chaque programme devrait vous fournir ce dont vous avez besoin:

START "title" [/D path] [options] "command" [parameters]

Chaque STARTappel exécute la commande donnée dans son paramètre et retourne immédiatement, sauf si elle est exécutée avec un /WAITcommutateur.

Cela s'applique aux applications de ligne de commande. Les applications sans ligne de commande retournent immédiatement de toute façon, donc pour être sûr, si vous souhaitez toutes les exécuter de manière asynchrone, utilisez START.

macbirdie
la source
D'accord merci. J'aurais dû lire attentivement chaque entrée help. :)
RichN
8
J'ai eu des problèmes avec ça l'autre jour. J'ai dû lancer 30 fenêtres d'explorateur pour un test de performance. Cela n'a pas fonctionné et ce n'était pas assez important pour moi de l'examiner ... j'ai commencé à naviguer à la place dans cette fenêtre et plusieurs heures plus tard, lorsque je l'ai fermée, une autre est apparue! Et j'étais comme quoi diable, fermé ... un autre est apparu! Après 4-5 fenêtres et beaucoup de choses, j'ai remarqué que le fichier batch fonctionnait toujours!
Jonas B le
3
Auto-publicité éhontée: j'ai déjà créé un lot qui peut fonctionner comme une sorte de pool de threads, juste pour les processus: stackoverflow.com/questions/672719/...
Joey
4
Si vous devez fournir des arguments ou si le chemin d'accès aux commandes contient des espaces, n'oubliez pas d'ajouter des guillemets. Dans ce cas, vous devez également fournir un titre pour la fenêtre d'ouverture de la console: start "" "[chemin vers la commande]" [command args]
Pierluigi
Y a-t-il un moyen de dire avec cette technique quand elle est terminée? Je lance ~ 30 copies de FILA DESTA et je veux qu'elles soient asynchrones, mais je veux aussi avoir une idée quand elles sont toutes faites.
Doug
68

En combinant quelques-unes des réponses précédentes, vous pouvez essayer start /b cmd /c foo.exe.

Pour un exemple trivial, si vous souhaitez imprimer les versions de java / groovy / grails / gradle, vous pouvez le faire dans un fichier batch:

@start /b cmd /c java -version
@start /b cmd /c gradle -version
@start /b cmd /c groovy -version
@start /b cmd /c grails -version

Si vous avez quelque chose comme Process Explorer (Sysinternals), vous verrez quelques processus enfants cmd.exe, chacun avec un processus java (selon les commandes ci-dessus). La sortie s'imprimera à l'écran dans n'importe quel ordre de fin.

start /b :  Start application without creating a new window. The
             application has ^C handling ignored. Unless the application
             enables ^C processing, ^Break is the only way to interrupt
             the application

cmd /c : Carries out the command specified by string and then terminates
djKianoosh
la source
13
il empêche la commande d'être renvoyée à la console. Dans les scripts batch, vous verrez parfois echo offau début ce qui, lorsque vous exécuterez le script, empêchera toutes les commandes d'être renvoyées à la console. Le @est similaire mais juste pour cette seule commande. Donc, parfois vous verrez @echo off.
djKianoosh
36

Vous pouvez utiliser la commande start pour générer des processus d'arrière-plan sans lancer de nouvelles fenêtres:

start /b foo.exe

Le nouveau processus ne pourra pas être interrompu avec CTRL-C; vous pouvez le tuer uniquement avec CTRL-BREAK (ou en fermant la fenêtre, ou via le Gestionnaire des tâches.)

sproaticus
la source
5
Où est BREAKle clavier ces jours-ci?
user2023370
1
@ user2023370 Toujours sur la touche Pause . La plupart des ordinateurs portables dépourvus de certaines touches prennent en charge les combinaisons de touches cachées .
Gerold Broser
23

Créez un fichier batch avec les lignes suivantes:

start foo.exe
start bar.exe
start baz.exe 

La commande start exécute votre commande dans une nouvelle fenêtre, de sorte que les 3 commandes s'exécutent de manière asynchrone.

Nikhil
la source
17

Utilisez la commande START :

start [programPath]

Si le chemin d'accès au programme contient des espaces, n'oubliez pas d'ajouter des guillemets. Dans ce cas, vous devez également fournir un titre pour la fenêtre d'ouverture de la console

start "[title]" "[program path]"

Si vous devez fournir des arguments, ajoutez-les à la fin (en dehors des guillemets de commande)

start "[title]" "[program path]" [list of command args]

Utilisez l'option / b pour éviter d'ouvrir une nouvelle fenêtre de console (mais dans ce cas, vous ne pouvez pas interrompre l'application en utilisant CTRL-C

Pierluigi
la source
10

Il existe une troisième option (et potentiellement beaucoup plus simple). Si vous souhaitez lancer plusieurs instances d'un même programme, l'utilisation d'un processeur de commande de style Unix comme Xargs ou GNU Parallel peut en faire un processus assez simple.

Il existe un clone win32 Xargs appelé PPX2 qui rend cela assez simple.

Par exemple, si vous souhaitez transcoder un répertoire de fichiers vidéo, vous pouvez exécuter la commande:

dir /b *.mpg |ppx2 -P 4 -I {} -L 1 ffmpeg.exe -i "{}" -quality:v 1 "{}.mp4"

En le séparant, dir /b *.mpgsaisit une liste de fichiers .mpg dans mon répertoire actuel, l' |opérateur redirige cette liste dans ppx2, qui construit ensuite une série de commandes à exécuter en parallèle; 4 à la fois, comme spécifié ici par l' -P 4opérateur. le-L 1 opérateur dit à ppx2 de n'envoyer qu'une seule ligne de notre liste de répertoires à ffmpeg à la fois.

Après cela, vous écrivez simplement votre ligne de commande ( ffmpeg.exe -i "{}" -quality:v 1 "{}.mp4"), et{} se substitue automatiquement à chaque ligne de votre liste de répertoires.

Ce n'est pas universellement applicable à tous les cas, mais c'est beaucoup plus facile que d'utiliser les solutions de contournement de fichier de commandes détaillées ci-dessus. Bien sûr, si vous ne traitez pas avec une liste de fichiers, vous pouvez également diriger le contenu d'un fichier texte ou de tout autre programme vers l'entrée de pxx2.

schmod
la source
1
Le dernier port xargs win32 fonctionne bien de nos jours (celui inclus avec git pour Windows de toute façon).
Peter M
C'est génial sauf que cela échoue à traiter les fichiers contenant des caractères Unicode. Avez-vous l'intention de prendre en charge les fichiers Unicode? Merci.
Gökhan Sever
@ GökhanSever Dans le passé, j'ai contourné ce problème en utilisant la forme "nom court" du chemin, qui ressemble à C: \ PROGRA ~ 1 \ WINDOW ~ 3 \ MYPROG ~ 1.EXE. Ce n'est pas beau, mais ça marche.
moltenform
-1

Je ne pouvais rien faire fonctionner J'ai fini par utiliser juste PowerShell pour démarrer des scripts bat .. parfois même démarrer cmd / c ne fonctionne pas je ne sais pas pourquoi .. J'ai même essayé des trucs comme start cmd / c notepad & exit

start-Process "c:\BACKUP\PRIVATE\MobaXterm_Portable\MobaXterm_Portable.bat" -WindowStyle Hidden
RmccurdyDOTcom
la source