Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Параллельное копирование файлов в bat. (http://forum.oszone.net/showthread.php?t=275614)

Dremor 12-01-2014 06:33 2287311

Параллельное копирование файлов в bat.
 
Привет всем.
Такой вопрос возник.

Есть два диапазона значений, постоянно вырастающих на единицу.
Одно лежит в одном диапазоне (допустим 1-10), другое (15-25).
Нужно создавать папки именованные значением переменной диапазона.
Т.е. папки 1\ 2\ 3\ 4\ 5\ 6\ и т.д.
В эти папки нужно копировать один и тот-же файл.

Нужно написать такой батник, чтобы копирование происходило параллельно.
Т.е. одновременно идёт создание папки допустим 1 и папки 15.

Проблема в том, что у меня постоянно выходит последовательное копирование при помощи for.
Код набросал, но так и не додумался как сделать параллельное копирование.
+ перед каждым копированием, нужно пинговать удаленный сервер (на самом деле 1,2,3 это цифры в IP, но не суть).

Iska 12-01-2014 06:59 2287314

Dremor, Ваши интервалы различны по длине: в одном 10 значений, в другом — 11.

Цитата:

Цитата Dremor
Нужно написать такой батник, чтобы копирование происходило параллельно.
Т.е. одновременно идёт создание папки допустим 1 и папки 15. »

Почему не «1», «2», «3», … «10», «15», «16», …«25» одновременно?

Цитата:

Цитата Dremor
(на самом деле 1,2,3 это цифры в IP, но не суть). »

Как раз таки суть. Рассказывайте подробно.

mwz 12-01-2014 12:31 2287434

Цитата:

Цитата Dremor
Нужно написать такой батник, чтобы копирование происходило параллельно »

В общих чертах: запускать из батника не просто "COPY", а "start cmd /c COPY" (то же -- с MD). Тогда переход к следующей команде исходного батника будет происходить не дожидаясь завершения текущей команды.
Да и слово "параллельно"... Вопрос, что быстрее происходит: исполнение команды -- или синтаксический разбор системой батника и переход к следующей строке.

Dremor 12-01-2014 15:01 2287545

Цитата:

@echo off

for /L %%i in (11,1,34) do call:pingtest %%i && if %errorlevel%==0 call:copyoper %%i

exit /b 0

setlocal
:pingtest
1>nul 2>&1 ping -n 1 -w 200 192.168.%1.1 && (echo 192.168.%1.1 = OK) || echo No connection with 192.168.%1.1 at %TIME% %DATE% && echo No connection with 192.168.%1.1 at %TIME% %DATE% >> errolog.txt
exit /b
endlocal

setlocal
:copyoper
1>nul 2>&1 md testf\192.168.%1.1 && 1>nul 2>&1 copy %COMPUTERNAME%.txt testf\192.168.%1.1
if %errorlevel%==0 echo File succesfully copied to 192.168.%1.1
endlocal
Вот пример кода батника copy1.bat, который вызывается run.bat
Как можно это реализовать при помощи "start cmd /c COPY" в цикле?

Цитата:

Как раз таки суть. Рассказывайте подробно.
Один и тот-же файл копируется на 192.168.%%i.1. где %%i += 1
Это я реализовал, но последовательно.

Foreigner 12-01-2014 15:28 2287557

Попробуй так:
Код:

@echo off
setlocal

for /l %%i in (11,1,34) do start /b cmd /c "ping -n 1 192.168.%%i.1 && ( xcopy %computername%.txt testfld\192.168.%%i.1\ )"


Dremor 12-01-2014 16:03 2287583

Спасибо, а как теперь организовать параллельную запись?
Т.е. два цикла, один этот (11,1,34), другой (36,1,79)?

Я просто не могу понять, как запустить два цикла параллельно.
Ладно если бы цикл в цикле был, но здесь в теле цикла реализовать это очень трудно.
Я то сделал два батника, copy1.bat и copy2.bat, они одинаковые, просто работают с двумя диапазонами.

Foreigner 12-01-2014 16:18 2287597

Dremor, Просто прописать в run.cmd
Код:

start copy.cmd 11 34
start copy.cmd 36 79

А в copy.cmd:
Код:

for /l %%i in (%1,1,%2) do ....
Т.е. получится, что запускается 2 копии copy.cmd c разными аргументами

И лучше copy.cmd назвать как-нибудь иначе, на всякий случай.

Dremor 12-01-2014 16:24 2287600

Спасибо, сегодня попробую обязательно.

Dremor 12-01-2014 16:57 2287632

Подскажите ещё пожалуйста, как послать вывод c copy.cmd на главное окно?
Т.е. я запустил run.bat, пошла copy.cmd и чтобы все ошибки она выводила в run.bat?

Iska 12-01-2014 17:00 2287636

Главное, чтобы размеры копируемого по сети были адекватными. Иначе параллелизация приведёт к противоположному от ожидаемого эффекту.

Dremor 12-01-2014 18:06 2287683

В общем попробЫвал все и все-равно возникают проблемы.
Нужно чтобы при отсутствии пинга выводилось сообщение об ошибке, а если связи нет, то и не должно быть копирования.
Для этого мне нужно объеденить проверку пинга в одну функцию, но этого не сделать.

В итоге сделал так, нормально не работает

test.cmd
Цитата:


@echo off
set fvar=%3

for /l %%i in (%1,1,%2) do (
(1>nul 2>&1 ping -n 1 192.168.%%i.1) && echo No connection to 192.168.%%i.1 || echo Con to 192.168.%%i.1 && (md test\192.168.%%i.1 && copy %fvar% test\192.168.%%i.1) || echo Cannot copy %fvar%
run.bat
Цитата:

@echo off

set filename="%COMPUTERNAME%.txt"

call make.bat %filename% && if %errorlevel%==0 (
start test.cmd 11 34 %filename%
start test.cmd 42 80 %filename%
)

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

Foreigner 12-01-2014 19:25 2287737

Dremor, У меня такой вариант работает:
Код:

@echo off
setlocal

set "exec=xcopy %computername%.txt D:\Downloads\%%%i.ru\"
set "error=echo wrong host %%%i.ru"

for %%i in (ya,щщ,юю) do start /b cmd /c "1>nul 2>&1 ping -n 1 %%i.ru && (%exec%) || (%error%)

У меня нет возможности пинговать устройства в локалке, поэтому взял существующий ya.ru и два заведомо ложных, в вашем случае измените на:
Код:

@echo off
setlocal

set "exec=xcopy %computername%.txt testfolder\192.168.%%%i.1\"
set "error=echo wrong ip 192.168.%%%i.1"

for /l %%i in (%1,1,%2) do start /b cmd /c "1>nul 2>&1 ping -n 1 192.168.%%i.1 && (%exec%) || (%error%)

PS. Для проверки пинга будет лучше и правильней такая конструкция:
Код:

... ping -n 1 192.168.%%i.1 | 1>nul findstr "TTL" && ( %exec% ) || ( %error% )

Dremor 12-01-2014 19:54 2287756

Исправил проверку пинга и вроде заработало, пока ещё решаю остальные вопросы :)
Ложная тревога, теперь с такой проверкой пинга в любом случае выдаёт ошибку wrong ip, хотя пингую локальный 192.168.1.1
:(

В случае же отсутствия строчки
Цитата:

| 1>nul findstr "TTL"
не выдается сообщение об ошибке пинга.
Файлы тоже копируются.
Хотя проверил сам, все айпишники не пингуются.

Разберусь - отпишусь, похоже ковычки где-то пропустил.

Dremor 12-01-2014 20:12 2287768

Теперь возникла еще проблема:
Мы количество отчетов об ошибках урезали, а нужно чтобы выдавались также ошибки о том, что файл не может быть копирован.
Т.е. на пинг проверили, а потом ещё на само копирование.

Да, ещё непонятно как вывести сообщения об ошибках в главное окно.
Или сделать так, чтобы работало только одно окно. (Встаёт проблема параллельности копирования)

Foreigner 12-01-2014 20:40 2287797

Dremor, Если не секрет, зачем эта параллельность? Просто возникают затруднения в написании, а выигрыш во времени скорее всего сомнительный. Убрать все эти start cmd и ничего не потеряешь. Файлы текстовые, так ведь, если тяжелые, то хотя бы запускать только xcopy.exe в нескольких экземплярах:
Код:

@echo off
setlocal

for /l %%i in (%1,1,%2) do (

    ping -n 1 192.168.%%i.1 | 1>nul findstr "TTL" && (

        start /b 1>nul 2>&1 xcopy %computername%.txt "folder\192.168.%%i.1\" || echo can't copy to folder\192.168.%%i.1

    ) || (

        echo ping error 192.168.%%i.1

))


Dremor 12-01-2014 20:44 2287801

Это мне так задали сделать, зачем я сам не понимаю.
Последовательно я давно все написал.

Вообще мне легче это всё в С++ сделать, чем париться с гениальной cmd, но надо значит надо :)

Спасибо за пример, я также сделал.
От этих скобочек уже голова болит.

Я уже по сути все сделал, осталось последнее условие.
Как сделать вывод в run.bat, когда start.cmd Отработали?

Т.е. операция прошла и мне нужно сделать вывод о том, что батник работу завершил и какой результат (ну тут понятно, еррорлевел наверное проще сделать).

Foreigner 12-01-2014 21:00 2287826

Цитата:

Цитата Dremor
Как сделать вывод в run.bat, когда start.cmd Отработали? »

Боюсь, что он ничего не знает о запущенных батниках, он просто запускает и прекращает свою работу. Можно конечно добавить waitfor:
Код:

:: run.cmd
@echo off

start 1.cmd

waitfor signal_name

Код:

:: 1.cmd

timeout 5
waitfor /si signal_name


Dremor 12-01-2014 21:07 2287839

Ох уж эти батники, я за день общения с ними (до этого вообще 0 знал по ним) свихнулся просто напросто.
Лучше бы был встроенный компилятор многих языков, написал код и всё.

Спасибо за помощь Foreigner, очень помог.

mwz 12-01-2014 23:06 2287967

Цитата:

Цитата Foreigner
И лучше copy.cmd назвать как-нибудь иначе, на всякий случай. »

"Эт точно!" Стандартная ошибка -- назвать .bat/.cmd именем существующей команды, а затем удивляться, почему всё работает не так как должно работать, если запускать (или изнутри другой программы передавать параметры) без явного указания расширения. :)

Dremor,
Да и run.bat лучше бы переобозвать (поскольку имя программ run.exe, как и launch.exe, тоже периодически попадается, и обработка может уйти к таким программам).


Время: 15:13.

Время: 15:13.
© OSzone.net 2001-