Основная проблема может быть решена с помощью опции /D
команды START , чтобы определить текущий каталог для запущенных процессов.Все index.js
ожидают, очевидно, что файл token.txt
находится в текущем каталоге и что текущий каталог является каталогом, содержащим оба файла.Windows устанавливает по умолчанию текущий каталог на каталог пакетного файла при двойном щелчке, например, по пакетному файлу activate.bat
.
@echo off
echo Starting all bots...
start "" /B /D"%~dp0test1" node index.js
start "" /B /D"%~dp0test2" node index.js
Первая строка аргумента в двойных кавычках интерпретируется командой START в качестве необязательного заголовка для окна консоли.node
запускается здесь без открытия окна консоли.Рекомендуется всегда определять заголовок при использовании команды START .В этом случае пустой заголовок окна, указанный с помощью ""
, является хорошим выбором, также как и при запуске приложения с графическим интерфейсом Windows, поскольку окно консоли вообще не открывается.
Подкаталоги test1
и test2
всегдав каталоге, содержащем командный файл run_all.bat
.По этой причине %~dp0
используется для ссылки на диск и путь аргумента 0, который является текущим исполняемым пакетным файлом.Это делает пакетный файл run_all.bat
сам по себе независимым от текущего каталога при выполнении run_all.bat
.
/
(косая черта) является разделителем каталогов в Linux / Mac.Но \
(обратная косая черта) следует использовать в Windows в путях к файлам / папкам, поскольку /
используется для параметров в Windows, за исключением приложений, перенесенных из Unix в Windows без адаптации к синтаксису Windows.Функции ядра Windows для доступа к файлам / папкам заменяют все /
на \
для автоматического исправления путей перед доступом к файловым системам Windows по соображениям совместимости, но определенно лучше записывать пути файлов / папок в сценариях Windows с текущим разделителем каталогов ине зависит от этого автоматического исправления ядра Windows.
%~dp0
расширяется до строки пути, всегда заканчивающейся обратной косой чертой.Поэтому не следует использовать дополнительную обратную косую черту при объединении этой динамической строки с фиксированным именем файла / папки / пути.В противном случае было бы два \
последовательно на исполнение.Функции ядра Windows для доступа к файлам / папкам также автоматически корректируются \\
в строке, ссылающейся на файл / папку, по \
.Но, опять же, лучше избежать этой ошибки.
Подробнее см. Статью Microsoft о Именовании файлов, путей и пространств имен .
Команда So START устанавливает теперь каталог, содержащий index.js
и token.txt
перед запуском node
с аргументом index.js
.
Лучшим решением было бы использование этого пакетного файла:
@echo off
echo Starting all bots...
for /F "delims=" %%I in ('dir "%~dp0index.js" /A-D-H /B /S 2^>nul') do start "" /B /D"%%~dpI" node index.js
Команда FOR выполняется в отдельном командном процессе с cmd.exe /C
(точнее %CompSpec% /C
в фоновом режиме командной строки:
dir "C:\Users\Simon\Desktop\bot\index.js" /A-D-H /B /S 2>nul
DIR выходыдля обработки STDOUT запущенного командного процесса
- в голом формате из-за опции
/B
- имен файлов с расширением и сполный путь из-за опции
/S
- для всех только не скрытых файлов из-за опции
/A-D-H
(атрибут не каталог и не скрытый) - с именем файла
index.js
, найденным в указанномкаталог или любой подкаталог из-за опции /S
.
TВывод сообщения об ошибке DIR для обработки STDERR при обнаружении чего-либо, соответствующего этим критериям, подавляется путем перенаправления на устройство NUL .
.Статья Microsoft о Использование операторов перенаправления команд для объяснения 2>nul
.Оператор перенаправления >
должен быть экранирован с помощью символа вставки ^
в командной строке FOR , чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , котораявыполняет встроенную командную строку dir
в отдельном командном процессе, запущенном в фоновом режиме.
FOR с опцией /F
захватывает выходные данные для обработки STDOUT запущенного фонового командного процесса и обрабатывает эти выходные данные после завершения запуска cmd.exe
.Пустые строки всегда игнорируются FOR , которых здесь нет.Строки, начинающиеся с ;
, по умолчанию также игнорируются FOR , поскольку точка с запятой является опцией конца строки по умолчанию.Невозможно, чтобы полное имя файла, выводимое DIR , начиналось с точки с запятой, и поэтому в этом случае можно сохранить значение по умолчанию eol=;
. FOR будет по умолчанию разделять каждую строку на подстроки с использованием обычного пробела и горизонтальной табуляции в качестве разделителей строк и назначать только первую строку с пробелом / символ табуляции для указанной переменной цикла.Такое поведение здесь нежелательно, поскольку путь к файлу может содержать также один или несколько пробелов.Поэтому поведение разделения строк отключается с помощью delims=
, который определяет пустой список разделителей, в результате чего всегда получается полное полное имя файла, присвоенное переменной цикла.
FOR выполняется для каждого вывода имени файла DIR команда START , как описано выше.Для START не имеет значения, если путь к каталогу, указанный в /D"..."
, не имеет или имеет обратную косую черту в конце.
Основное преимущество этого второго решения для пакетного файла по сравнению с первымможно легко увидеть: run_all.bat
нельзя редактировать при удалении или добавлении дополнительных каталогов с помощью index.js
.
Но имейте в виду, что слишком большое количество параллельных node
экземпляров может привести к обратным результатам в зависимости от того, какой код в index.js
делает.Поэтому может быть полезно расширить пакетный файл, чтобы он начинал не более чем x node
, и останавливать выполнение пакетного файла до тех пор, пока один экземпляр node
не завершит сам себя, прежде чем запускать следующий экземпляр при достижении максимально допустимого числа параллельных операций.node
экземпляров.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
dir /?
echo /?
for /?
start /?
PS: предлагаю уточнитьnode
по крайней мере с расширением файла и лучше всего с полным путем, чтобы сделать пакетный файл независимым от переменных среды PATHEXT
и PATH
.