Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Изменение глобальной переменной в дочернем процессе.

Ответить
Настройки темы
CMD/BAT - [решено] Изменение глобальной переменной в дочернем процессе.

Экзорцист


Сообщения: 969
Благодарности: 127

Профиль | Отправить PM | Цитировать


Здравствуйте.
Помогите разобраться. Есть два исполняемых фала со следующим содержимым:
xxx.cmd
Код: Выделить весь код
echo off
SET MY_ERRORLEVEL1=1
echo xxx1 MY_ERRORLEVEL1=%MY_ERRORLEVEL1%
pause
start yyy.cmd
echo xxx2 MY_ERRORLEVEL1=%MY_ERRORLEVEL1%
pause
pause
yyy.cmd
Код: Выделить весь код
echo off
echo yyy1 MY_ERRORLEVEL1=%MY_ERRORLEVEL1%
SET MY_ERRORLEVEL1=2
echo yyy2 MY_ERRORLEVEL1=%MY_ERRORLEVEL1%
pause
exit
Пользователь запускает файл xxx.cmd. В нем определяется переменная MY_ERRORLEVEL1. Затем из этого файла следует вызов дочернего файла yyy.cmd. При выполнении видно, что значение переменной MY_ERRORLEVEL1 в процесс yyy.cmd передается и им можно воспользоваться. Затем происходит изменение переменной MY_ERRORLEVEL1 и выход из файла. При этом новое значение переменной MY_ERRORLEVEL1 в процессе xxx.cmd (в родительском) не доступно, оно осталось старым и равно 1.
Вопрос - как в дочернем процессе изменить значение переменной, определенной в родительском процессе? Причем изменить так, чтобы новое значение было доступно в родительском процессе?
Спасибо.
P.S. общая задача такова - необходимо сделать бэкап 9 папок с разных компов. При этом, для экономии времени, копирование запускается в 9 процессов. При этом, на время выполнения дочерних процессов копирования, родительский процесс встает на паузу (ping -n 500 localhost > nul). Копирование может закончится ошибкой доступа - поэтому хочу возвращать из дочернего процесса значение переменной %ERRORLEVEL%, значение которой присвою переменным MY_ERRORLEVEL1..MY_ERRORLEVEL9

Отправлено: 11:24, 09-02-2015

 

Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата Michael:
При выполнении видно, что значение переменной MY_ERRORLEVEL1 в процесс yyy.cmd передается и им можно воспользоваться. »
Не так. Создаётся копия окружения родительского процесса «cmd.exe» (в котором исполняется пакетный файл «xxx.cmd»), и порождённый процесс «cmd.exe» (в котором исполняется пакетный файл «yyy.cmd») работает именно с ней.

Цитата Michael:
Затем происходит изменение переменной MY_ERRORLEVEL1 и выход из файла. При этом новое значение переменной MY_ERRORLEVEL1 в процессе xxx.cmd (в родительском) не доступно, оно осталось старым и равно 1. »
Оно и не будет доступно, поскольку изменение происходит в окружении порождённого процесса «cmd.exe», являющемся копией окружения родительского процесса «cmd.exe».

Цитата Michael:
Вопрос - как в дочернем процессе изменить значение переменной, определенной в родительском процессе? Причем изменить так, чтобы новое значение было доступно в родительском процессе? »
Ответ: в рамках заданной категории и выбранного механизма исполнения — никак.

Цитата Michael:
P.S. общая задача такова - необходимо сделать бэкап 9 папок с разных компов. При этом, для экономии времени, копирование запускается в 9 процессов. При этом, на время выполнения дочерних процессов копирования, родительский процесс встает на паузу (ping -n 500 localhost > nul). Копирование может закончится ошибкой доступа - поэтому хочу возвращать из дочернего процесса значение переменной %ERRORLEVEL%, значение которой присвою переменным MY_ERRORLEVEL1..MY_ERRORLEVEL9 »
Задача понятна.

Суть проблемы в том, что мы можем либо исполнять последовательно, получая результат по ErrorLevel/ExitCode дочернего процесса, либо, как у Вас, параллельно — не имея возможности получить результат исполнения по ErrorLevel/ExitCode дочернего процесса.

Я бы подумал о переходе на WSH («WshRemote»), либо PowerShell («WinRM»). Если никак — попробуйте, например, писать результат из дочерних пакетных файлов в единый текстовый файл, по строчке на машину. Родительский пакетный файл очищает/удаляет его, затем запускает по «start» N порождённых пакетных файлов отдельно. Каждый из них по исполнении дописывает свой результат в единый текстовый файл. Всё это время, родительский пакетный файл в бесконечном цикле ожидания раз, допустим, в пять секунд проверяет этот текстовый файл на предмет наличия в нём записей от всех порождённых дочерних файлов. Как только все записи окажутся в наличии — происходит выход из цикла ожидания, разбор этого текстового файла и вывод результатов.
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:49, 09-02-2015 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Сообщения: 1754
Благодарности: 965

Профиль | Цитировать


Дочерний батник можно завернуть в for /f:
Код: Выделить весь код
:: 1.cmd

@echo off
setlocal

set "var=1"
echo %var% 1.cmd

for /f %%i in ('2.cmd') do set "var=%%i"

echo %var% 1.cmd
Код: Выделить весь код
:: 2.cmd

@echo off
setlocal

set /a var+=1
echo %var%

Отправлено: 21:45, 09-02-2015 | #3


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Foreigner, как это будет выглядеть со «start 2.cmd»?!

Отправлено: 22:09, 09-02-2015 | #4


Экзорцист


Сообщения: 969
Благодарности: 127

Профиль | Отправить PM | Цитировать


Iska, спасибо. Пока попробую остановиться на использовании временных файлов, создаваемых в дочерних процессах и анализируемых в родительском.
Foreigner, если я правильно понял ваш код, то выполнение файла 1.cmd остановится на время выполнения файла 2.cmd. Правильно? Меня такой вариант не устраивает - слишком долго придется ждать. И еще. Не могли бы вы объяснить 2 момента - зачем в начале используется :: и зачем нужны кавычки в строке set "var=1"? Спасибо.
upd: :: просто комментарий с именем файла?

Последний раз редактировалось Michael, 10-02-2015 в 08:38.


Отправлено: 08:32, 10-02-2015 | #5


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата Michael:
зачем в начале используется :: »
Вместо команды комментария REM используется псевдометка.

Цитата Michael:
и зачем нужны кавычки в строке set "var=1"? »
Дабы ограничить правую часть в присваивании. В данном случае нет разницы по сравнению с вариантом без кавычек.

Цитата Michael:
upd: :: просто комментарий с именем файла? »
Фактически — да.
Это сообщение посчитали полезным следующие участники:

Отправлено: 09:39, 10-02-2015 | #6


Ветеран


Сообщения: 1754
Благодарности: 965

Профиль | Цитировать


Цитата Michael:
Меня такой вариант не устраивает - слишком долго придется ждать. »
Просто не вник в суть вопроса. Сделал акцент на возвращение переменной из дочернего батника. В любом случае можно запустить несколько копий родительского командного файла с разными аргументами (название компьютера, папки). Вопрос реализации.

Отправлено: 10:12, 10-02-2015 | #7


Экзорцист


Сообщения: 969
Благодарности: 127

Профиль | Отправить PM | Цитировать


Цитата Iska:
Создаётся копия окружения родительского процесса «cmd.exe» »
Т.е. исходя из этого, в каждом вновь запущенном процессе будет своя переменная ERRORLEVEL со своим значением. Правильно?

Отправлено: 10:42, 10-02-2015 | #8


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата Michael:
Т.е. исходя из этого, в каждом вновь запущенном процессе будет своя переменная ERRORLEVEL со своим значением. »
Своя переменная окружения «MY_ERRORLEVEL1».

Отправлено: 11:33, 10-02-2015 | #9


Экзорцист


Сообщения: 969
Благодарности: 127

Профиль | Отправить PM | Цитировать


Iska, нет, меня интересует именно системная переменная ERRORLEVEL. Она будет своя в каждом процессе?
P.S. своя - в смысле независимая от других процессов.

Отправлено: 11:44, 10-02-2015 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Изменение глобальной переменной в дочернем процессе.

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - [решено] Реализация функций длины переменной, выделение подстроки с параметрами в переменной. NiOl Скриптовые языки администрирования Windows 7 31-01-2019 19:58
CMD/BAT - [решено] В переменной содержится имя переменной opravdin Скриптовые языки администрирования Windows 3 28-01-2013 11:11
DNS в дочернем домене niklep Microsoft Windows NT/2000/2003 1 23-01-2012 10:49
V. 5.5/2000/2003 - Установка Exchange 2010 в дочернем домене. coldnet Microsoft Exchange Server 3 11-02-2011 14:00
[решено] Глобальный каталог в дочернем домене SanyaJoker Microsoft Windows NT/2000/2003 33 28-04-2009 14:47




 
Переход