Выполнение команд пакетного файла Windows асинхронно

187

Скажи, если у меня есть

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

Как мне запустить их все из пакетного файла асинхронно, то есть, не дожидаясь остановки предыдущей программы?

RichN
источник

Ответы:

254

Использование STARTкоманды для запуска каждой программы должно дать вам то, что вам нужно:

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

Каждый STARTвызов запускает команду, указанную в ее параметре, и немедленно возвращается, если не выполняется с /WAITпереключателем.

Это относится к приложениям командной строки. В любом случае приложения без командной строки немедленно возвращаются, поэтому, если вы хотите, чтобы все выполнялось асинхронно, используйте START.

macbirdie
источник
Хорошо спасибо. Я должен был прочитать каждую запись helpвнимательно. :)
RichN
8
У меня действительно были проблемы с этим на днях. Мне пришлось запустить 30 окон проводника для теста производительности. Не сработало, и мне было недостаточно важно разобраться в этом ... вместо этого я начал просматривать его в этом окне, а через несколько часов, когда я закрыл его, всплыло еще одно! И я был как то, что, черт возьми, закрыл это .. другой всплыл! После 4-5 окон и много чего **** я заметил, что пакетный файл все еще работает!
Джонас Б.
3
Бесстыдная самореклама: однажды я создал пакет, который может функционировать как некий пул потоков, только для процессов: stackoverflow.com/questions/672719/…
Joey
4
Если вам нужно предоставить аргументы или если путь к командам содержит пробелы, не забудьте добавить кавычки. В этом случае вам также необходимо указать заголовок открывающегося окна консоли: start "" "[path to command]" [command args]
Pierluigi
Есть ли способ сказать с этой техникой, когда это сделано? Я запускаю ~ 30 копий FILA DESTA, и я хочу, чтобы они были асинхронными, но я также хочу иметь некоторую идею, когда они все будут готовы.
Дуг
68

Объединяя пару предыдущих ответов, вы можете попробовать start /b cmd /c foo.exe.

Для тривиального примера, если вы хотите распечатать версии java / groovy / grails / gradle, вы можете сделать это в пакетном файле:

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

Если у вас есть что-то вроде Process Explorer (Sysinternals), вы увидите несколько дочерних процессов cmd.exe, каждый из которых имеет процесс Java (согласно приведенным выше командам). Вывод будет распечатан на экране в любом порядке.

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
источник
13
это предотвращает вывод команды на консоль. В пакетных сценариях иногда вы видите echo offв начале, что при выполнении сценария будет предотвращать вывод всех команд на консоль. Это @похоже, но только для этой единственной команды. Так что иногда вы увидите @echo off.
djKianoosh
36

Вы можете использовать команду запуска для запуска фоновых процессов без запуска новых окон:

start /b foo.exe

Новый процесс не будет прерываться с помощью CTRL-C; Вы можете убить его только с помощью CTRL-BREAK (или закрыв окно, или через диспетчер задач.)

sproaticus
источник
5
Где сейчас BREAKна клавишах?
user2023370
1
@ user2023370 Все еще на клавише Pause . Большинство ноутбуков, в которых отсутствуют определенные клавиши, поддерживают скрытые комбинации клавиш .
Герольд Брозер
23

Создайте командный файл со следующими строками:

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

Команда запуска запускает вашу команду в новом окне, поэтому все 3 команды будут выполняться асинхронно.

Нихилу
источник
17

Используйте команду START :

start [programPath]

Если путь к программе содержит пробелы, не забудьте добавить кавычки. В этом случае вам также необходимо указать заголовок открывающегося окна консоли.

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

Если вам нужно предоставить аргументы, добавьте их в конце (за пределами кавычек команды)

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

Используйте параметр / b, чтобы избежать открытия нового окна консоли (но в этом случае вы не можете прервать приложение с помощью CTRL-C

Пьерлуиджи
источник
10

Есть третий (и потенциально гораздо более простой) вариант. Если вы хотите раскрутить несколько экземпляров одной программы, использование командного процессора в стиле Unix, такого как Xargs или GNU Parallel, может сделать этот процесс довольно простым.

Есть клон win32 Xargs под названием PPX2, который делает это довольно просто.

Например, если вы хотите перекодировать каталог видеофайлов, вы можете выполнить команду:

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

Разбирая это, dir /b *.mpgзахватывает список файлов .mpg в моем текущем каталоге, |оператор передает этот список в ppx2, который затем строит серию команд, которые будут выполняться параллельно; 4 за один раз, как указано здесь -P 4оператором. -L 1Оператор говорит ppx2 только послать одну линию нашего каталога листинг на FFmpeg в то время.

После этого вы просто пишете свою командную строку ( ffmpeg.exe -i "{}" -quality:v 1 "{}.mp4") и {}автоматически подставляете для каждой строки списка каталогов.

Это не универсально применимо к каждому случаю, но намного проще, чем использование обходных путей командного файла, описанных выше. Конечно, если вы не имеете дело со списком файлов, вы также можете передать содержимое текстового файла или любой другой программы на вход pxx2.

schmod
источник
1
Последний порт xargs win32 в настоящее время работает хорошо (в любом случае он входит в состав git для windows).
Питер М
Это здорово, за исключением того, что он не работает с файлами, содержащими символы Юникода. Есть ли планы по поддержке файлов Unicode? Спасибо.
Гекхан Север
@ GökhanSever В прошлом я работал над этой проблемой, используя форму пути «короткое имя», которая выглядит как C: \ PROGRA ~ 1 \ WINDOW ~ 3 \ MYPROG ~ 1.EXE. Не красиво, но это работает.
расплавленный
-1

Я не мог заставить что-либо работать, я закончил тем, что просто использовал powershell для запуска сценариев bat ... Иногда даже запуск cmd / c не работает, не знаю почему .. Я даже пробовал такие вещи, как start cmd / c notepad & exit

start-Process "c:\BACKUP\PRIVATE\MobaXterm_Portable\MobaXterm_Portable.bat" -WindowStyle Hidden
RmccurdyDOTcom
источник