Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Операционные системы » Microsoft Windows » Задачи на bat-файлах 12

Модерирует : KLASS, IFkO

KLASS (06-03-2018 00:44): Объединение тем по сценариям: Сценарии Windows
 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

   

hErAx

Редактировать | Цитировать | Сообщить модератору
Задачи на bat-файлах 12
Предыдущие части: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
Вопросы, задачи и их решения по работе с командными файлами, а также сопутствующие ссылки.

 
Важно: копируя батник через буфер обмена из форума не забывайте удалять пробелы в конце каждой строки, т.к. в некоторых случаях из-за этого программа будет работать неправильно!!! Чтобы не копировались концевые пробелы из форума, жмите на ссылку "Редактировать" в посте, и уже из редактора копируйте батник без пробелов.
 
Также для удаления концевых пробелов пользуйтесь скриптом от Nagual, или VBS-Скрипт-Модулем от ViSiToR.
 
Для перекодирования кирилицы 866<—>1251 пользуйтесь онлайн сервисом Перекодировщик кириллицы

 
Дополняем шапку: добавляем готовые решения, полезные ссылки.
 
Примечание: Большие куски кода заключайте в тэг [more]  
 
Смежные темы:
В помощь системному администратору » Автоматизация администрирования
Программы » Командная строка, батники\сценарии
 
Полезные ссылки
 
Полезные утилиты
 
Готовые решения и частые вопросы:
  • При запуске batch-файла от Администратора текущая директория меняется на system32
  • Встроенный справочник по командам
  • Создание помощи по всем командам консоли 2000 и XP
  • Делаем паузу в командном файле стандартными средствами Windows
  • Альтернативные решения »
  • Работа с текстом, датой, и файлами »
  • Администрирование, автоматизация и сеть »
  • Работа с переменными и параметрами ком. строки »
     
    Описания работы команд и символов участниками темы:
    · setlocal enabledelayedexpansion и переменные окружения
    · символы & и && в командной строке
    · Переменная %0

  • Отправлено: 01:53 25-10-2015 | Исправлено: Paromshick, 21:51 18-12-2017
    BorlandIMHO

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Pasha_ZZZ

    Цитата:
    про скорострельность

    На обработке одной строки - разницы в скорострельности как бы и никакой.


    ----------
    http://www.imho.ws

    Всего записей: 2376 | Зарегистр. 12-10-2006 | Отправлено: 00:43 17-12-2016
    Furee



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    BorlandIMHO
    Pasha_ZZZ
    Спасибо! Все получилось!
    Правда поменял искомое "hosts" на "etc", т.к., в моем случае из-за недостатка прав высыпало ошибку:

    Код:
    Не найден путь: C:\Windows\SYSTEM32\drivers\etc

    Всего записей: 766 | Зарегистр. 13-10-2014 | Отправлено: 00:49 17-12-2016
    GCRaistlin



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    latin

    Цитата:
    Мне больше нравится так как правильно и оптимально.

    Оптимально пользоваться delayed expansion всегда, когда возможны спецсимволы в значениях. Как я заметил выше, затруднительно разработать алгоритм, который будет эскейпить только спецсимволы вне двойных кавычек.
    При этом delayed expansion следует включать только на время работы с такими значениями, а не глобально. Сохранить значение переменной, созданной внутри setlocal, после endlocal можно так:

    Код:
     
    setlocal enabledelayedexpansion
    set Var=!windir!
    for /f "delims=" %%A in ("!Var!") do (
      endlocal
      set Var=%%A
    )
     

     

    Цитата:
    А какие имеют?

    Если в разбираемой строке FOR встречает значение с "*" и "?", он при очередной итерации вместо этого значения будет подставлять имена файлов, совпадающих с соответствующей маской.

    ----------
    Magically yours
    Raistlin

    Всего записей: 3961 | Зарегистр. 18-04-2005 | Отправлено: 16:37 17-12-2016
    latin



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    GCRaistlin
    благодарю за ответ!
    И, кстати, про оптимальность и оптимизацию - вот здесь нашёл некоторые тесты раскрытия переменных при отложенном исполнении.

    Всего записей: 781 | Зарегистр. 01-03-2006 | Отправлено: 20:11 17-12-2016
    VictorMan



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Кстати, насчет enabledelayedexpansion
    я попался как-то: нужно было назначить на несколько команд, а я оставил до конца .cmd.
    Ничего же страшного вроде, там оставалось несколько команд простых вроде, чего мельтешить....
    И вдруг - неправильно работают эти оставшиеся команды...выяснилось, что дальше была работа с файлами в текущей папке, а папка, где был .cmd, имела в своем имени "!".
    Сообразил не сразу, т.к. в командах же нет "!"
    ========================================
    В рабочем варианте папка была без "!", а попался я при отладке - привык выделять актуальные папки с помощью !!!.
    Вроде удобно, в сортировке всегда сверху...

    Всего записей: 2447 | Зарегистр. 26-09-2001 | Отправлено: 20:34 17-12-2016 | Исправлено: VictorMan, 12:51 20-12-2016
    GCRaistlin



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VictorMan
    Думаю, стоит уточнить это:

    Цитата:
    delayed expansion следует включать только на время работы с такими значениями

    Delayed expansion следует отключать, если верно одно из:

    1. До конца скрипта работать со значениями, которые могут содержать спецсимволы, не требуется.
    2. До следующей работы со значениями, которые могут содержать спецсимволы, требуется работать со значениями, которые могут содержать "!" (в том числе имена файлов, получаемые в цикле FOR), и переменные, их содержащие, нельзя раскрывать по "!".

    В остальных случаях delayed expansion следует оставлять включенным и раскрывать все переменные по "!".
    Основное зло при использовании delayed expansion - падение производительности - не в самом раскрытии по "!", а в затратах времени на выполнение пары команд "setlocal enabledelayedexpansion" + "endlocal": ~ в 25 раз больше, чем на отложенное раскрытие в команде типа "set Var=!windir!", и это еще без учета времени на вынос значения переменной за пределы setlocal с помощью FOR.
    Более точные цифры сейчас представить не могу, но идея понятна.

    ----------
    Magically yours
    Raistlin

    Всего записей: 3961 | Зарегистр. 18-04-2005 | Отправлено: 12:43 18-12-2016 | Исправлено: GCRaistlin, 12:48 18-12-2016
    Smitis



    Silver Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    latin

    Цитата:
    И, кстати, про оптимальность и оптимизацию - вот здесь нашёл некоторые тесты раскрытия переменных при отложенном исполнении.

    Эти тесты сравнения переменных %% и !! бессмыслены, о чём я на том форуме писал.


    ----------
    Разум когда-нибудь победит

    Всего записей: 3177 | Зарегистр. 09-02-2003 | Отправлено: 13:52 18-12-2016
    YuS_2



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VictorMan  17-12-2016

    Цитата:
    я попался как-то: нужно было назначить на несколько команд, а я оставил до конца .cmd.  
    Ничего же страшного вроде, там оставалось несколько команд простых вроде, чего мельтешить....  
    И вдруг - неправильно работают эти оставшиеся команды...выяснилось, что дальше была работа с файлами в текущей папке, а папка, где был .cmd, имела в своем имени "!".  

    Восклицательный знак в путях? Ничего страшного. Одна беда - пакетник придется корректировать.
     
    Вот для наглядности сценарий, демонстрирующий различные ошибки в путях с "!", при раскрытии переменных и варианты обхода этой "проблемы":

    Код:
    @echo off
     
    set "src=%~dp0"
     
    echo ============================ - 1
    dir /b/s/a "%src%"
    echo ============================ - 1
    echo.
     
    setlocal enabledelayedexpansion
     
    echo ============================ - 2
    echo Ошибка в пути, содержащем "^!":
    echo ==
    dir /b/s/a "%src%"
    echo ============================ - 2
    echo.
    echo ============================ - 2.1
    echo Из пути будет "съеден" символ "^!":
    echo ==
    for /f "delims=" %%i in ('dir /b/s/a "!src!"') do echo "%%i"
    echo ============================ - 2.1
    echo.
     
    echo ============================ - 3
    dir /b/s/a "!src!"
    echo ============================ - 3
    echo.
     
    echo ============================ - 3.1
    setlocal disabledelayedexpansion
    for /f "delims=" %%i in ('dir /b/s/a "%src%"') do echo "%%i"
    setlocal enabledelayedexpansion
    echo ============================ - 3.1
    echo.
     
    echo ============================ - 3.2
    cmd /c for /f "delims=" %%i in ('dir /b/s/a "!src!"') do @echo "%%i"
    echo ============================ - 3.2
    echo.
     
    endlocal
    pause

    где:
    1 - обычное %-раскрытие  
    2, 2.1 - возможные ошибки
    3, 3.1, 3.2 - варианты обхода проблемы...

    Всего записей: 3218 | Зарегистр. 03-02-2009 | Отправлено: 22:48 18-12-2016
    GCRaistlin



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Smitis

    Цитата:
    Эти тесты сравнения переменных %% и !! бессмыслены

    Почему?

    ----------
    Magically yours
    Raistlin

    Всего записей: 3961 | Зарегистр. 18-04-2005 | Отправлено: 11:20 19-12-2016
    Smitis



    Silver Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    GCRaistlin
    Переменные %% раскрываются ДО выполнения команды и блока команд между (), т.е ОДИН раз перед выполнением. Переменные !! раскрываются ВО ВРЕМЯ выполнения команд, т.е. на каждой итерации цикла.


    ----------
    Разум когда-нибудь победит

    Всего записей: 3177 | Зарегистр. 09-02-2003 | Отправлено: 11:35 19-12-2016
    GCRaistlin



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Smitis
    Хех, а ведь и правда. Изменил методику тестирования - вызываю из цикла подпрограмму, в которой содержится тестируемая операция:
    Подробнее...
    Запускал тестирование несколько раз. Результаты прелюбопытные:
    1
    2
    3
    Скорость !-раскрытия и %-раскрытия ОДИНАКОВАЯ. 10000 присвоений значения переменной что с тем, что с другим занимают около 3 с. Такие дела.

    ----------
    Magically yours
    Raistlin

    Всего записей: 3961 | Зарегистр. 18-04-2005 | Отправлено: 23:26 19-12-2016
    yurkesha



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    GCRaistlin
    только если в цикле используются внешние переменные содержимое которых не меняется при каждой итерации то мы получим РАЗНОЕ количество раскрытий. Каждый инструмент уместен на месте - молотком забивают, клещами - вытаскивают и так далее...
    ТОЧКА.

    ----------
    Всем непричастным рекомендую прогулки на свежем воздухе

    Всего записей: 2741 | Зарегистр. 15-12-2003 | Отправлено: 08:41 20-12-2016
    GCRaistlin



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    yurkesha
    Прочтите еще раз внимательно то, о чем написано выше, а уже потом ставьте ЗНАКИ ПРЕПИНАНИЯ .
     
    Добавлено:
    Добавлю, хотя, в принципе, это и так очевидно, что включенное delayed expansion на скорость %-раскрытия не влияет. Т. е. если delayed expansion включено и в раскрываемых значениях гарантированно нет "!", то в циклах можно вполне пользоваться %-раскрытием, не выключая предварительно delayed expansion, - как раз чтобы не тратить времени на раскрытие при каждой итерации.

    ----------
    Magically yours
    Raistlin

    Всего записей: 3961 | Зарегистр. 18-04-2005 | Отправлено: 08:59 20-12-2016 | Исправлено: GCRaistlin, 09:32 20-12-2016
    Smitis



    Silver Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Цитата:
    и в раскрываемых значениях гарантированно нет "!"

    А это как раз следствие того, что переменные %% раскрываются до выполнения - в них можно помещать выполняемый код (а в переменные !! нельзя).
    Ещё интересный момент - двойной %% перед переменными цикла ставится не просто так, перед выполнением он как и положено заменяется на одиночный % и уже во время выполнения интерпретируется как признак переменной цикла. Такой вот пример

    Код:
    @echo off
    set "i=%%a" &:: в переменную будет записано %a и в дальнейшем при выполнении интерпретировано как переменная цикла
    set "j=echo !i!"
    setlocal enabledelayedexpansion
    echo %i%
    for /l %%a in (1,1,4) do (
      echo %i%
      %j%
    )

     
    В чистой же командной строке (не в командном файле) механизм раскрытия переменных работает несколько по-другому.


    ----------
    Разум когда-нибудь победит

    Всего записей: 3177 | Зарегистр. 09-02-2003 | Отправлено: 11:25 21-12-2016
    GCRaistlin



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Smitis

    Цитата:
    помещать выполняемый код ... в переменные !! нельзя

    Скорее, не всякий код можно:

    Код:
     
    set a=echo a
    setlocal enabledelayedexpansion
    !a!
     



    ----------
    Magically yours
    Raistlin

    Всего записей: 3961 | Зарегистр. 18-04-2005 | Отправлено: 12:24 21-12-2016
    Smitis



    Silver Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Цитата:
     
    Скорее, не всякий код можно

    Сейчас точно не помню уже, давно экспериментировал.


    ----------
    Разум когда-нибудь победит

    Всего записей: 3177 | Зарегистр. 09-02-2003 | Отправлено: 13:34 21-12-2016
    DCT

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Может кому-то будет полезно.
    Была задача разбудить утром в определенное время компьютер из ждущего или спящего режима, потушить экран (ибо компьютером может быть ноут) выполнить пару команд и после их выполнения погрузить компьютер в сон. Все это нужно было сделать батником, который при надобности запускать на ночь перед "усыплением" компа.
    Перегемороился с кучей плохих вариантов, пока не нашел хорошее решение с помощью утилитки Wake On Stand By, nircmd и следующего батника:
     

    Код:
    wosb.exe /run /systray tm="05:30:00"
    nircmdc.exe monitor off
    команда 1
    команда 2
    start wosb.exe /run /standby

    Такое решение работает под XP/Win7 , с восьмеркой пишут, что будут проблемы, которые вроде бы (лично не проверял) должны были пофиксить в десятке. Пишут, что так можно разбудить компьютер даже из hibernate-а.
    Огромный бонус утилитки в том, что для планирования пробуждения не нужно больше никаких дополнительных действий (ни планировщика, ни лазанья в биос, ни WOL пакета).

    Всего записей: 792 | Зарегистр. 22-12-2005 | Отправлено: 00:50 22-12-2016
    VitaminP



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    DCT

    Цитата:
    Была задача разбудить утром в определенное время компьютер из ждущего или спящего режима

    Это можно стандартным планировщиком сделать (поставить галку: разбудить для запуска этого задания), а все остальное скриптом без дополнительных программ.

    Всего записей: 306 | Зарегистр. 28-08-2013 | Отправлено: 11:14 22-12-2016 | Исправлено: VitaminP, 11:15 22-12-2016
    DCT

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VitaminP
    Можно то можно, но не совсем .
    Нужно по обстоятельствам либо поставить, либо не поставить задание на утреннее выполнение, делать это буду не я. Сейчас это реализовано единтсвенным кликом по ярлыку на рабочем столе, который запускает батник.
     
    Ваш вариант:
    зайти в планировщик, добавить новое задание (не ошибиться с датой и временем), не забыть поставить галочку "разбудить компьютер". Можно было бы сделать это так же через ярлык, доп.параметрами at/schtasks, но тут засада: они не дают добавить задачу с галочкой "разбудить компьютер для выполнения этого задания"

     
    А теперь представьте, как это объяснять людям, никогда не работавшим с планировщиком, и насколько велика вероятность, что в самый ответственный момент они случайно не сделают критическую ошибку? В общем, bat файлы как всегда рулят).
     
    ЗЫ. И еще есть засада в том, что "правильно" усыпить компьютер из командной строки - нетривиальная задача. Гуляющий по сети вариант через rundll32 глючный, рабочие варианты - это либо как у меня в батнике "wosb.exe /run /standby", либо командой "psshutdown -d -t 0 /accepteula" (вот пока не узнал о ключе /accepteula, пару раз сильно попадал с консольными утилитами Русиновича при запуске батников на новых машинах) соответствующей утилитой psshutdown.

    Всего записей: 792 | Зарегистр. 22-12-2005 | Отправлено: 20:17 22-12-2016 | Исправлено: DCT, 20:25 22-12-2016
    RomanKotel



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Здравствуйте! Принесли комп починить, но кто-то выдернул из него RAM. Есть задача узнать размер установленной оперативной памяти из реестра host-системы Windows (когда она еще работала!) при загрузке с LiveCD. По вопросу нашел только батник GetMem.bat How can I retrieve the amount of memory in a computer from the registry?

    Код:
     
    @echo off
    if \{%1\}==\{\} @echo Syntax GetMem MB \[Computer\]&goto :EOF
    setlocal ENABLEDELAYEDEXPANSION
    set comp=%2
    if "%comp%" EQU "" set comp=%computerName%
    set comp=%comp:"=%
    set comp=\\%comp:\=%
    set Key="%Comp%\HKLM\HARDWARE\RESOURCEMAP\System Resources\Physical Memory"
    set Key="HKLM\HARDWARE\RESOURCEMAP\System Resources\Physical Memory"
    :: Retrieve the binary string
    For /f "Tokens=2,3" %%m in ('REG QUERY %Key% /V .Translated^|find "REG_RESOURCE_LIST"') do (set val=%%n)
    :: determine the length of the binary string.
    call VarLen val Len
    :: determine the position of the last 8 bytes of the binary string.
    set /a pos=%len% - 8
    set rev=!val:~%pos%!
    :: Since the binary value stores the memory DWORD in reverse notation,
    :: set the proper hexadecimal representation.
    set hex=0x%rev:~6,1%%rev:~7,1%%rev:~4,1%%rev:~5,1%%rev:~2,1%%rev:~3,1%%rev:~0,1%%rev:~1,1%
    :: Multiply each hexadecimal 2 character number by the proper bit shift.
    set /a wk1=%hex:~0,4% * 16777216
    set /a wk2=0x%hex:~4,2% * 65536
    set /a wk3=0x%hex:~6,2% * 256
    set /a wk4=0x%hex:~8,2%
    :: Add each decimal value.
    set /a wrk=%wk1% + %wk2% + %wk3% + %wk4%
     :: Convert to megabytes.
    set /a mem=%wrk% / 1048576
    :: Attempt to account for incorrect memory detection by making the results a multiple of 32MB.
    set /a mem=%mem% + 31
    set /a mem=%mem% / 32
    set /a mem=%mem% * 32
    endlocal&set /a %1=%mem%
     

     
    который думаю прикрутить через RunScanner PEbuilder плагин, позволяющий редактировать реестр host-системы. Не могу понять куда батник выводит значение в МБ, даже на живой системе.
    VarLen.bat лежит здесь

    Код:
     
    @echo off
    if \{%2\}==\{\} @echo Syntax: call VarLen VarName Length&goto :EOF
    if not defined %1 @echo Syntax: call VarLen VarName Length, VarName not defined.&goto :EOF
    set /a %2 = 0
    call echo.%%%1%%>%TEMP%\$VarLen$.tmp
    for %%n in (%TEMP%\$VarLen$.tmp) do set/a %2 = %%~zn - 2
    del /q %TEMP%\$VarLen$.tmp
     

    Всего записей: 35 | Зарегистр. 19-06-2008 | Отправлено: 00:33 23-12-2016 | Исправлено: RomanKotel, 00:40 23-12-2016
       

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

    Компьютерный форум Ru.Board » Операционные системы » Microsoft Windows » Задачи на bat-файлах 12
    KLASS (06-03-2018 00:44): Объединение тем по сценариям: Сценарии Windows


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru