Я хочу вызвать другой экземпляр CMD и передать ему данные из родительского экземпляра.
Я знаю об общем пути использования переменных, но в данном случае это нецелесообразно, так как endlocal и мостовое соединение были бы слишком неудобны (пришлось бы передавать десятки переменных). Я также знаю, что я мог бы использовать временные файлы для легкого переноса всех нужных мне данных, но это оставило бы нежелательные следы. EDIT: setx также можно использовать довольно успешно.
я ищуконкретнодля чего-то вроде общепринятого использования аргументов, например:
test.bat -setvar"variable"="value" -setvar...
Я уже находил один способ с его ограничениями
Нашел в другой теме, что можно добавить команду в конец start cmd
start cmd /c call "test.bat" ^& PAUSE
Конечно, мы можем это изменить.
start cmd /c call PAUSE ^& TIMEOUT 5 ^& PAUSE ^& test.bat
Команды не могут содержать "" и, я подозреваю, какие-либо специальные символы. Это создает проблему при попытке переноса сложных переменных.
Говоря о специальных символах:
start cmd /c call (PAUSE) ^& (TIMEOUT 5) ^& (REM !"#¤%&/=?`´^*"-.,_:;\*~¨) ^& test.bat
Это вообще не сработает. Я, возможно, смогу избежать интерпретации, но в случае некоторых переменных у меня может не быть роскоши знать достаточно значений, чтобы иметь возможность обработать их во что-то, с чем я смогу справиться. -- На самом деле, кажется, скобки не допускаются.
Одна из главных задач, которую мне нужно выполнить, — это передача имен томов, что легко осуществимо, но этого недостаточно.
start cmd /c call echo \\?\Volume{6537febd-01bc-11d6-adb5-806e6f6e6963}\ ^& TIMEOUT 5 ^& PAUSE ^& test.bat
Возможно, об этом уже где-то говорилось, и если так, то проблема в том, что я не могу найти нужные ключевые слова или параллели к соответствующим темам.
решение1
Дочерний cmd
экземплярнаследуетвсе переменные окружения из родительского. Доказательство: создадим два пакетных скрипта:
Test1.bat
@setlocal
@set _batch
@set "_batchParentName=%~nx0"
@set "_batchParentPath=%~dp0"
@set "_batchParentSpec=< LSS > GTR & amper | pipe"
start "%~n0" cmd /C call "test.bat" "%_batchParentSpec%" %* ^& pause
@set _batch
Тест.bat
@setlocal
@set _batch
@echo %~n0: %%* = %*
Вывод родительского cmd
экземпляра:
d:\bat>test1.bat first "1<2" third
Environment variable _batch not defined
d:\bat>start "test1" cmd /C call "test.bat" "< LSS > GTR & amper | pipe" first "1<2" third
& pause
_batchParentName=test1.bat
_batchParentPath=D:\bat\
_batchParentSpec=< LSS > GTR & amper | pipe
d:\bat>
cmd
Вывод дочернего экземпляра из test.bat
:
_batchParentName=test1.bat
_batchParentPath=D:\bat\
_batchParentSpec=< LSS > GTR & amper | pipe
test: %* = "< LSS > GTR & amper | pipe" first "1<2" third
Press any key to continue . . .
Примечание справаstart
синтаксис командыс "title"
:
START "title" [/D path] [options] "command" [parameters]
Всегда включайте НАЗВАНИЕ, это может быть простая строка, например «Мой сценарий» или просто пара пустых кавычек «». Согласно документации Microsoft, заголовок необязателен, но в зависимости от других выбранных параметров у вас могут возникнуть проблемы, если он будет пропущен.
Гарантироватькомандаstart
несодержат /I
переключатель опций (из start /?
):
/I The new environment will be the original environment passed
to the cmd.exe and not the current environment.
Чтобы исключить еще одну возможность изменения дочерней среды, включите переключение /D
следующим cmd
образом:
start "test1" cmd /D /C call "test.bat"
Согласно cmd /?
:
/D Disable execution of AutoRun commands from registry
решение2
Вы можете использовать его setx
для установки глобальной переменной среды Windows.
Чтобы использовать, setx
просто напишите это: setx "name" "variable"
где имя — это простое имя, а переменная — это переменная, которую вы хотите установить.
Ознакомьтесь setx /?
со всеми опциями и параметрами, если вы хотите узнать о них немного подробнее.
Обратите внимание, что setx будет сохранять переменные непосредственно в кусте текущего пользователя реестра. Это означает, что вам не нужны никакие административные привилегии, но это также означает, что переменные не будут напрямую доступны в текущем сеансе cmd. Используйте обычный, если set
вы просто хотите хранить переменные локально.
Конечно, вы также можете сохранить локальную переменную в глобальной, как показано в следующем примере:
@echo off
:: store "test" in variable "a"
set a=test
:: make this variable global
setx a %a%
Как вы можете видеть в примере выше, %a%
ссылается на переменную в локальной области видимости, а setx делает ее общедоступной.
Чтобы сбросить глобальную переменную, вызовите эту команду, setx "name" ""
например:setx a ""
Также хорошо понимать: вы не можете изменить один экземпляр cmd, используя setx в другом. Как только вы запускаете окно cmd, только set может изменять его переменные внутри, а setx может сохранять их снаружи. (при выходе, как вам угодно)