Поиск подстроки в выводе команды ipconfig

alex_diablo

Постоянный участник
Сообщения
144
Реакции
9
появилась еще одна задачка, связанная с поиском...
нужно сделать поиск в результатах команды ipconfig

задаем переменные:

CMD/BATCH:
subnet1="10.6"
subnet2="10.7"
subnet3="10.8"
subnet4="10.9"
......

далее:

CMD/BATCH:
ipconfig

в результатах вывода команды нужно искать подсеть, в частности - первые 2 октета (они заданы переменными в начале)
и дальше в зависимости от того, какая это подсеть (10.6, 10.7, 10.8 и т.д.) -
переменной subnet присвоить соответствующую переменную выше,
например: если у нас подсеть 10.7 - то subnet=subnet2.
если мы запустили скрипт в подсети 10.9 - то subnet=subnet4

вроде элементарно, но чет туплю...
 
Сохранять в кодировке OEM-866.

CMD/BATCH:
@echo off
SetLocal EnableExtensions

set "subnet1=10.6"
set "subnet2=10.7"
set "subnet3=10.8"
set "subnet4=10.9"

set subnetCnt=4

For /F "delims=" %%a in ('ipconfig /all^| findstr /i /c:"Маска подсети" /c:"Subnet"') do (
  For /L %%C in (1,1,%subnetCnt%) do echo %%a|>NUL call find /i "%%subnet%%C%%" && set subnetNum=%%C
)
if defined subnetNum (
  call echo Found subnet: "subnet%subnetNum%" - "%%subnet%subnetNum%%%"
) else (
  echo Subnet not found!
)
pause
 
Сохранять в кодировке OEM-866.

CMD/BATCH:
@echo off
SetLocal EnableExtensions

set "subnet1=10.6"
set "subnet2=10.7"
set "subnet3=10.8"
set "subnet4=10.9"

set subnetCnt=4

For /F "delims=" %%a in ('ipconfig /all^| findstr /i /c:"Маска подсети" /c:"Subnet"') do (
  For /L %%C in (1,1,%subnetCnt%) do echo %%a|>NUL call find /i "%%subnet%%C%%" && set subnetNum=%%C
)
if defined subnetNum (
  call echo Found subnet: "subnet%subnetNum%" - "%%subnet%subnetNum%%%"
) else (
  echo Subnet not found!
)
pause

ого! не думал, что такой код в итоге получится)
а нельзя ли сделать вот так (подглядел вот здесь: https://safezone.cc/threads/peremennye-v-cmd-komanda-set-i-arifmetika.22660/ ):

CMD/BATCH:
@echo off
ipconfig | findstr /i /c:"ipv4" >ip.txt
set /p ip="" <ip.txt

if "%ip:10.5=%" neq "%ip%"  set a=subnet1
if "%ip:10.6=%" neq "%ip%"  set a=subnet2
if "%ip:10.7=%" neq "%ip%"  set a=subnet3
echo %a%

Согласен, выглядит кривенько, но де делает ли этот код то же самое?
 
Так Вам что искать нужно ip-адрес с префиксом или маску подсети?
Потому что я сделал поиск именно подсети...
а нельзя ли сделать вот так
Команда
Будет сохранять в переменную только первую строку файла ip.txt
Соответственно Вы будете проверять адрес только первого (неизвестно какого ?) адаптера из нескольких. А там могут быть не только физические, но и виртуальные.
if "%ip:10.5=%" neq "%ip%" set a=subnet1
Да. Это вполне приемлемая проверка.
Только вот Вам придется каждый раз вносить правки в код, если потребуется поменять условия.
А в моем варианте, только добавить еще одну переменную и указать их кол-во.
Для поиска по всем адаптерам Ваш код можно переписать подобным образом:
CMD/BATCH:
@echo off
SetLocal EnableExtensions

For /F "delims=" %%a in ('ipconfig ^| find /i "ipv4"') do call :FindIP "%%a"
if Defined a echo %a%
pause
goto: eof

:FindIP
set "ip=%~1"
if "%ip:10.5=%" neq "%ip%"  set a=subnet1
if "%ip:10.6=%" neq "%ip%"  set a=subnet2
if "%ip:10.7=%" neq "%ip%"  set a=subnet3
exit /B
 
Последнее редактирование:
мне нужно узнать, в какой подсети запускается скрипт. в данном случае - глядя на ipv4. но насчет того, что может быть несколько сетевых адаптеров, где не обязательно первый может быть в нужной подсети... да.. об этом я не подумал...
Так Вам что искать нужно ip-адрес с префиксом или маску подсети?
Потому что я сделал поиск именно подсети...

Команда

Будет сохранять в переменную только первую строку файла ip.txt
Соответственно Вы будете проверять адрес только первого (неизвестно какого ?) адаптера из нескольких. А там могут быть не только физические, но и виртуальные.

Да. Это вполне приемлемая проверка.
Только вот Вам придется каждый раз вносить правки в код, если потребуется поменять условия.
А в моем варианте, только добавить еще одну переменную и указать их кол-во.
Для поиска по всем адаптерам Ваш код можно переписать подобным образом:
CMD/BATCH:
@echo off
SetLocal EnableExtensions

For /F "delims=" %%a in ('ipconfig ^| find /i "ipv4"') do call :FindIP "%%a"
if Defined a echo %a%
pause
goto: eof

:FindIP
set "ip=%~1"
if "%ip:10.5=%" neq "%ip%"  set a=subnet1
if "%ip:10.6=%" neq "%ip%"  set a=subnet2
if "%ip:10.7=%" neq "%ip%"  set a=subnet3
exit /B

а как сделать то же самое, только с заданием переменных в начале, чтобы не приходилось каждый раз править код, как вы сделали с маской?
на самом деле, вопрос стоит немного другим образом...
поясню подробнее:
есть скажем, несколько филиалов офиса... в каждом филиале своя подсеть. (10.1, 10.2, 10.3 и т.д.)
в каждом филиале соответственно свой файловый сервер.

CMD/BATCH:
set folder=0

set office1=\\server1\soft\
set office2=\\server2\soft\
set office3=\\server3\soft\

и т.д.

задача состоит в том, что в зависимости от того, в какой подсети мы запускаем скрипт,
переменной FOLDER должно присвоиться значение одной из переменных office (1,2,3 и тд.)

т.е. после выполнения поиска нашей подсети,
команда echo %folder% должна вывести соответствующий путь, например, если у нас
подсеть 10.2 - то переменной FOLDER должно присвоиться значение: \\server2\soft\
Сохранять в кодировке OEM-866.

CMD/BATCH:
@echo off
SetLocal EnableExtensions

set "subnet1=10.6"
set "subnet2=10.7"
set "subnet3=10.8"
set "subnet4=10.9"

set subnetCnt=4

For /F "delims=" %%a in ('ipconfig /all^| findstr /i /c:"Маска подсети" /c:"Subnet"') do (
  For /L %%C in (1,1,%subnetCnt%) do echo %%a|>NUL call find /i "%%subnet%%C%%" && set subnetNum=%%C
)
if defined subnetNum (
  call echo Found subnet: "subnet%subnetNum%" - "%%subnet%subnetNum%%%"
) else (
  echo Subnet not found!
)
pause

не совсем понял, как работает данный код, но независимо от того, что задано в переменных subnet1-4, результат выполнения постоянно выдает: Founde subnet: "subnet4"
 
задача состоит в том, что в зависимости от того, в какой подсети мы запускаем скрипт,
Еще раз говорю, не путайте подсеть и адресацию IP-адресов/шлюз. У Вас разные шлюзы, на не подсети. Подсети у всех могут быть одинаковыми (по-умолчанию, 255.255.255.0), шлюзы кстати, тоже.

Чтобы искать по разным октетам IP в моем первом коде + иметь возможность сопоставить этим октетам разные каталоги:

CMD/BATCH:
@echo off
SetLocal EnableExtensions

set subnetCnt=4

set "subnet1=10.6"
set "subnet2=10.7"
set "subnet3=10.8"
set "subnet4=10.9"

set "office1=\\server1\soft\"
set "office2=\\server2\soft\"
set "office3=\\server3\soft\"
set "office4=\\server4\soft\"

For /F "delims=" %%a in ('ipconfig^| find /i "ipv4"') do (
  For /L %%C in (1,1,%subnetCnt%) do echo %%a|>NUL call find /i "%%subnet%%C%%" && set subnetNum=%%C
)
if defined subnetNum call set office=%%office%subnetNum%%%
echo Your Folder is: %office%

if not defined subnetNum echo Subnet not found!
pause
 
Еще раз говорю, не путайте подсеть и адресацию IP-адресов/шлюз. У Вас разные шлюзы, на не подсети. Подсети у всех могут быть одинаковыми (по-умолчанию, 255.255.255.0), шлюзы кстати, тоже.

Чтобы искать по разным октетам IP в моем первом коде + иметь возможность сопоставить этим октетам разные каталоги:

CMD/BATCH:
@echo off
SetLocal EnableExtensions

set subnetCnt=4

set "subnet1=10.6"
set "subnet2=10.7"
set "subnet3=10.8"
set "subnet4=10.9"

set "office1=\\server1\soft\"
set "office2=\\server2\soft\"
set "office3=\\server3\soft\"
set "office4=\\server4\soft\"

For /F "delims=" %%a in ('ipconfig^| find /i "ipv4"') do (
  For /L %%C in (1,1,%subnetCnt%) do echo %%a|>NUL call find /i "%%subnet%%C%%" && set subnetNum=%%C
)
if defined subnetNum call set office=%%office%subnetNum%%%
echo Your Folder is: %office%

if not defined subnetNum echo Subnet not found!
pause

запускаю скрипт и результат его работы:

Код:
Your folder is:
Subnet not found.

что то не так в коде...
 
Я проверял. У меня все работало.

Присылайте файл, созданный командой:
Код:
ipconfig > ip.txt
 
кстати, этот код работает, только если использовать findstr...

Для поиска по всем адаптерам Ваш код можно переписать подобным образом:
CMD/BATCH:
@echo off
SetLocal EnableExtensions

For /F "delims=" %%a in ('ipconfig ^| find /i "ipv4"') do call :FindIP "%%a"
if Defined a echo %a%
pause
goto: eof

:FindIP
set "ip=%~1"
if "%ip:10.5=%" neq "%ip%"  set a=subnet1
if "%ip:10.6=%" neq "%ip%"  set a=subnet2
if "%ip:10.7=%" neq "%ip%"  set a=subnet3
exit /B
 
Вообщем пообщались по скайпу.
Как оказалось, на рабочем столе у alex_diablo, лежал файл find.bat, который постоянно мешал и запускался вместо команды find.
 
Еще раз говорю, не путайте подсеть и адресацию IP-адресов/шлюз. У Вас разные шлюзы, на не подсети. Подсети у всех могут быть одинаковыми (по-умолчанию, 255.255.255.0), шлюзы кстати, тоже.

Чтобы искать по разным октетам IP в моем первом коде + иметь возможность сопоставить этим октетам разные каталоги:

CMD/BATCH:
@echo off
SetLocal EnableExtensions

set subnetCnt=4

set "subnet1=10.6"
set "subnet2=10.7"
set "subnet3=10.8"
set "subnet4=10.9"

set "office1=\\server1\soft\"
set "office2=\\server2\soft\"
set "office3=\\server3\soft\"
set "office4=\\server4\soft\"

For /F "delims=" %%a in ('ipconfig^| find /i "ipv4"') do (
  For /L %%C in (1,1,%subnetCnt%) do echo %%a|>NUL call find /i "%%subnet%%C%%" && set subnetNum=%%C
)
if defined subnetNum call set office=%%office%subnetNum%%%
echo Your Folder is: %office%

if not defined subnetNum echo Subnet not found!
pause

а вот этот код отрабатывает не совсем корректно, т.к. если мы находимся в одной из подсетей , которая задана одной из переменной sunnet (например 10.6) и наш айпишник 10.6.3ю115, то все ок.
если же мы запускаем из другой подсети, которая у нас не определена переменной и наш айпишник скажем - 192.168.1.50, то переменной %office% никакого значения не присваивается, но скрипт при этом продолжает выполняться. т.е. если после строк:
CMD/BATCH:
if defined subnetNum call set office=%%office%subnetNum%%%
echo Your Folder is: %office%
добавить set folder=%office%
goto psexec
то переменной %folder% ничего не присвоится, т.к. переменная %office% у нас пустая,
но переход по метке psexec будет осуществлен как будто без ошибок, но при этом дальнейшая работа скрипта будет невозможна, т.к. все завязано на переменной %folder%
т.е. тут нужна проверка вида: если мы в другой подсети, которая не была заранее определена, выдать сообщение что то тпа: пути не найдены, подсеть не определена, задайте подсеть и пути в соответствующих переменных и выйти из скрипта...
как то так...
т.е. у нас задача - найти соответствие фактческого айпишника сетевого адаптера заданной переменной, а не просто проверка существования subnetNum
 
Последнее редактирование:
выдать сообщение что то тпа: пути не найдены
Сообщение выдается:
Код:
if not defined subnetNum echo Subnet not found!
Вам нужно только заменить его на команду выхода.
т.е. у нас задача - найти соответствие фактческого айпишника сетевого адаптера заданной переменной, а не просто проверка существования subnetNum
Если не найден заранее указанный в скрипте subnetNum, значит нет и парной к нему папке, если только Вы не планируете указывать в скрипте октеты без соответствующих им папок.
 
сделал так: если у нас айпишник к примеру, 192.168.1.13 и он не прописан в коде и соответственно нет соответствующей ему папки, то завершаем работу скрипта.
если у нас скажем, айпишник 10.6.1.15 , то переходим по метке psexec.

но тогда не работает поиск файла psxec.exe
хотя вроде все нужные ему для этого переменные заданы... в чем косяк?


CMD/BATCH:
set subnetCnt=3

set "subnet1=10.6"
set "subnet2=10.7"
set "subnet3=10.8"

set "office1=\\server1\Soft\Developers_Tools\Unity"
set "office2=\\server2\soft\"
set "office3=\\server3\soft\"

For /F "delims=" %%a in ('ipconfig^| find /i "ipv4"') do (
  For /L %%C in (1,1,%subnetCnt%) do echo %%a|>NUL call find /i "%%subnet%%C%%" && set subnetNum=%%C
  )
if defined subnetNum (call set office=%%office%subnetNum%%% & call set folder=%%office%% & goto psexec)
pause
if not defined subnetNum echo Subnet not found!
exit

:psexec

:: default path for psexec:
set "psexecfolder=%folder%"
:: try if psexec exist in defoult folder. if no set path manually
:psexec1
cls
echo.
echo   .... Searching PsExec in default folder ...
echo.
echo.
For /f "delims=" %%a in ('dir /b /s /a-d "%psexecfolder%" ^| find /i "psexec.exe"') do call :psexec2 "%%a"
if defined psexec (goto begin) else (cls & echo. & echo. & echo.  PsExec not found in default folder. ^
Try to search manually: )
echo.
echo.
set /p psexecfolder=" Enter path for PsExec: "
goto psexec1

:psexec2
set "psexec=%~1"
exit /b
 
но тогда не работает поиск файла psxec.exe
Я вот не пойму, зачем искать хорошо известный файл, если он у Вас уже заранее должен лежать рядом с батником?
CMD/BATCH:
set office=%%office%subnetNum%%% &
Опять пробел лишний :(
И еще:
CMD/BATCH:
call set folder=%%office%% &
Если хотите использовать пробелы, то ставьте кавычки. Только не всё после знака равенства, а вот так:
CMD/BATCH:
call set "folder=%%office%%" & следующая команда
Я же говорю, Вам нужно было расставить по коду:
CMD/BATCH:
echo "%переменная%"
pause
и Вы сразу нашли бы все ошибки, к примеру:
CMD/BATCH:
:psexec

:: default path for psexec:
set "psexecfolder=%folder%"
echo set "psexecfolder=%folder%"
pause
Это некорректный поиск:
CMD/BATCH:
For /f "delims=" %%a in ('dir /b /s /a-d "%psexecfolder%" ^| find /i "psexec.exe"') do call :psexec2 "%%a"
Правильно делать так (не зря для этого как раз dir и предназначена):
CMD/BATCH:
For /f "delims=" %%a in ('dir /b /s /a-d "%psexecfolder%\psexec.exe"') do call :psexec2 "%%a"
Но я бы скинул ее в папку батника или в системный каталог и не морочил бы себе голову.

Зачем этот переход?
CMD/BATCH:
:psexec2
set "psexec=%~1"
exit /b
Можно было внутри цикла просто написать:
CMD/BATCH:
... do set "psexec=%%a"
 
Последнее редактирование модератором:
set office=%%office%subnetNum%%% &
Опять пробел лишний :(

а как в данном случае правильно должно быть? вот так?

CMD/BATCH:
set office=%%office%subnetNum%%%& goto ...


Но я бы скинул ее в папку батника или в системный каталог и не морочил бы себе голову.

Зачем этот переход?
предполагается вероятность, что не всегда и не в каждой шаре может лежать psexec в одном и том же месте (пути к шарам везде разные).
и еще: запускаться скрипт может на любом компе, и не факт, что там есть psexec, тем более лежащий в системном каталоге. НО предполагается
что он лежит находится где то в общей файловой шаре, где мы и производим поиск. для этого сделана эта проверка. чтобы не указывать
путь явно. либо подскажите, как указать абсолютный путь до файла по умолчанию и сделать дополнительно проверку, что если файл существует,
использовать этот путь. если нет - искать его...
 
Последнее редактирование:
а как в данном случае правильно должно быть? вот так?
Да.
предполагается вероятность, что не всегда и не в каждой шаре может лежать psexec в одном и том же месте (пути к шарам везде разные).
Так вот у меня исходя из этого и вопрос - зачем Вы запускаете программу psexec из-под шары, а не локально?
либо подскажите, как указать абсолютный путь до файла по умолчанию и сделать дополнительно проверку, что если файл существует,
использовать этот путь. если нет - искать его...
Еще раз повторюсь, программа ложится рядом с батником, при этом путь к ней не нужно задавать вообще и ничего искать не нужно.
То что Вы открываете файл, находящийся на шаре не означает, что он на ней же выполняется. Все работает по другому и гораздо сложнее, чем Вы предполагаете.
Если рассказать кратко. На Вашем ПК запускается psexec, который инициирует подключение к удаленному ПК через общий ресурс Admin$,
после чего на удаленном ПК создается служба, которая и обрабатывает все дальнейшие запросы, отправленные с Вашего ПК.
В случае, когда Вы открываете psexec.exe с удаленного ПК, то происходит все лишь еще одно лишнее действие, программа копируется с удаленного ПК во временную папку
на Вашем локальном ПК, после чего запускается на Вашем ПК.
 
Да.

Так вот у меня исходя из этого и вопрос - зачем Вы запускаете программу psexec из-под шары, а не локально?

Еще раз повторюсь, программа ложится рядом с батником, при этом путь к ней не нужно задавать вообще и ничего искать не нужно.
То что Вы открываете файл, находящийся на шаре не означает, что он на ней же выполняется. Все работает по другому и гораздо сложнее, чем Вы предполагаете.
Если рассказать кратко. На Вашем ПК запускается psexec, который инициирует подключение к удаленному ПК через общий ресурс Admin$,
после чего на удаленном ПК создается служба, которая и обрабатывает все дальнейшие запросы, отправленные с Вашего ПК.
В случае, когда Вы открываете psexec.exe с удаленного ПК, то происходит все лишь еще одно лишнее действие, программа копируется с удаленного ПК во временную папку
на Вашем локальном ПК, после чего запускается на Вашем ПК.

так я же и пояснил... может возникнуть вероятность, что нужно запустить скрипт на другом компе (не на своем обычном), есть доступ к шаре, где постоянно лежит скрипт... достаточно просто запустить его... не задумываясь о том, что нужно что то куда то откуда то скопировать...
во всяком случае, таково было требование начальства... чтобы любой чел мог запустить скрипт при необходимости, не задумывась о том, что у него на компе может чего то не быть, например того же псэкзека... на крайний случай, можно сделать ярлык на запуск батника из шары... тогда даже и пути до него знать не обязательно...
 
Назад
Сверху Снизу