Имя пользователя:
Пароль:
 | Правила  

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

Ответить
Настройки темы
CMD/BAT - Результат выполнения команды в переменную

Пользователь


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

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


Здравствуйте.

Есть задача получить скриптом некоторые smart атрибуты.
Смарт получаю через запуск Smartmontools
Код: Выделить весь код
c:\Temp\smart\smartctl.exe -a /dev/sda
На выходе этой команды будет много строк, хочу весь вывод загнать в переменную, которую буду парсить и выбирать нужные значения.
Не получается вывод команды передать в переменную

Код: Выделить весь код
@echo off
SetLocal EnableExtensions
for /F %%i in ('c:\Temp\smartmontools-6.6-1.win32-setup\bin\smartctl.exe "-a /dev/sda"') do set report=%%i
echo %report%
В report попадает только одно слово Use, как при запуске c:\Temp\smartmontools-6.6-1.win32-setup\bin\smartctl.exe без параметров.
Хотел бы обойтись без создание вспомогательного файла, куда перенаправить вывод команды.
Прошу совета.

Отправлено: 13:54, 20-11-2018

 

Аватара для Elven

Ветеран


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

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


работает как при запуске без параметров, потому что параметров как бы и нет, они в кавычках не воспринимаются.
весь вывод загнать в переменную не получится, разве что одну строку из вывода.
Код: Выделить весь код
for /F "delims=" %%i in ('c:\Temp\smartmontools-6.6-1.win32-setup\bin\smartctl.exe -a /dev/sda') do set report=%%i
echo %report%
но в приведенном примере туда попадет только одна строка (последняя), ибо переменная report при каждой итерации будет перезаписываться. Если нужно гонять именно весь вывод, а не какую-то конкретную строку, то можно использовать перенаправление вывода в файл, и парсить уже его, например.
Код: Выделить весь код
c:\Temp\smartmontools-6.6-1.win32-setup\bin\smartctl.exe -a /dev/sda >>d:\smart.log
или выдергивать нужные строки прямо сразу из вывода, и если нужно совать в переменную
Код: Выделить весь код
for /F "delims=" %%i in ('c:\Temp\smartmontools-6.6-1.win32-setup\bin\smartctl.exe -a /dev/sda ^| findstr UDMA_CRC_Error_Count') do set report=%%i
echo %report%
Это сообщение посчитали полезным следующие участники:

Отправлено: 14:20, 20-11-2018 | #2



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

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


Ветеран


Contributor


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

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


Цитата densan:
На выходе этой команды будет много строк, хочу весь вывод загнать в переменную, которую буду парсить и выбирать нужные значения.
Не получается вывод команды передать в переменную »
Цитата Elven:
весь вывод загнать в переменную не получится »
Можно загнать не в одну переменную, а во множество, например, переменных с номерами в именах. У меня нет Вашей программы smartctl.exe, привожу пример с командой Dir. Забираю каждую строку выдачи команды Dir в переменные @_1001 @_1002 ... а затем выдаю их на экран. Как уж с значениями этих переменных поступать - дело Ваше.
Код: Выделить весь код
@Echo Off
cls
	Set /A NNNN=1000
	FOR /F "usebackq delims=" %%i IN (`2^>nul Dir /B /S /A:-D "Z:\Box_In\Мой контент\Книги\Дискета_от_книги\"`) DO Call :Mass "%%i"

	FOR /F "usebackq tokens=1* delims==" %%i IN (`Set @_`) DO Echo %%j
pause
GoTo :Eof

:Mass
	Set /A NNNN+=1
	Set "@_%NNNN%=%~1"
GoTo :Eof
Идею подсмотрел у alpap

"В лоб" весь вывод загнать в переменную не получится. Но, если нельзя, а очень хочется, то можно, только надо придумать свой разделитель строк вместо CrLf , например, Ы (чтоб никто не догадался, или вообще, какой-нибудь символ псевдографики, например, ░).
Код: Выделить весь код
@Echo Off
cls
	Set "Out="
	Set "Delim=Ы"
	FOR /F "usebackq delims=" %%i IN (`2^>nul Dir /B /S /A:-D "Z:\Box_In\Мой контент\Книги\Дискета_от_книги\"`) DO Call :String "%%i"

	Echo %Out%
pause
GoTo :Eof

:String
	Set "Out=%Out%%~1%Delim%"
GoTo :Eof
Но, возможно, при этом получим очень длинную строку и получим ошибку и радость от такой строки очень сомнительна - её обработать гораздо труднее, чем в предыдущем случае.

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 20-11-2018 в 16:23.

Это сообщение посчитали полезным следующие участники:

Отправлено: 15:16, 20-11-2018 | #3


Ветеран


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

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


Цитата densan:
которую буду парсить и выбирать нужные значения »
вот тут подробнее
согласен с megaloman и Elven, что помещать весь вывод (особенно из нескольких строк) в одну переменную это и сложно и неудобно и чревато, тут или действительно через файл или почему нельзя распарсивание вывода сразу поместить в код, давайте целиком задачу. Вот еще вариант попеременного вывода, при большом количестве строк с него нет также никакого толку (надо сразу разбирать)
Код: Выделить весь код
@echo off
set "comand=title /?"

setlocal enabledelayedexpansion
 for /f "delims=" %%a in ('"%comand%"') do set /a n+=1& set "$_!n!=%%a"
 for /f %%a in ('set $_^|find /c /v ""') do set m=%%a
 echo Вывод, например, второй переменной: !$_2!
 echo ___________________________________________________
 echo:
 echo Вывод всех переменных ^(строк^)
 echo ---------------------------------------------------
 for /l %%n in (1 1 %m%) do for /f "tokens=2 delims==" %%a in ('set $_%%n') do echo %%a
 :: Можно в файл загнать
 >log.txt (for /l %%n in (1 1 %m%) do for /f "tokens=2 delims==" %%a in ('set $_%%n') do @echo %%a)
endlocal
pause
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:35, 20-11-2018 | #4


Ветеран


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

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


Если нужен весь вывод с последующим парсингом — я бы вообще работал с WSH/PoSH, наподобие:
Скрытый текст
Код: Выделить весь код
Option Explicit

Const strPath2smartctl = "%ProgramFiles%\smartmontools\bin\smartctl.exe"

Const WshRunning  = 0
Const WshFinished = 1
Const WshFailed   = 2


Dim strAbsolutePath2smartctl
Dim strOutput


With WScript.CreateObject("WScript.Shell")
	strAbsolutePath2smartctl = .ExpandEnvironmentStrings(strPath2smartctl)
	
	If WScript.CreateObject("Scripting.FileSystemObject").FileExists(strAbsolutePath2smartctl) Then
		With .Exec(strAbsolutePath2smartctl & " -a /dev/sda")
			If .Status <> WshFailed And .Status = WshRunning Then
				strOutput = ""
				
				Do
					strOutput = strOutput & .StdOut.ReadAll()
					
					WScript.Sleep 100
				Loop Until .Status = WshFinished
				
				WScript.Echo strOutput
			Else
				WScript.Echo "Can't execute [" & strAbsolutePath2smartctl & "]."
				WScript.Quit 2
			End If
		End With
	Else
		WScript.Echo "Can't find executive file [" & strAbsolutePath2smartctl & "]."
		WScript.Quit 1
	End If
End With

WScript.Quit 0

И потом парсите полученный в strOutput вывод как душеньке будет угодно, в том числе и регулярками.
Это сообщение посчитали полезным следующие участники:

Отправлено: 19:38, 20-11-2018 | #5


Пользователь


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

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


Цитата Iska:
WSH/PoSH »
PS или WSH нельзя по условиям задачи. Скрипт будет запускаться в ограниченной среде, где WSH/PoSH запрещен или отсутствует.

Задача: посредством Smartmontools снять смарт атрибуты и передать их в ПО мониторинга. Хотелось бы вывод
Код: Выделить весь код
c:\Temp\smart\smartctl.exe -a /dev/sda
Скрытый текст
smartctl 6.6 2017-11-05 r4594 [i686-w64-mingw32-win7(64)-sp1] (sf-6.6-1)
Copyright (C) 2002-17, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family: SandForce Driven SSDs
Device Model: SanDisk SDSSDA120G
Serial Number: 162213353535
LU WWN Device Id: 5 001b44 4a4a8b409
Firmware Version: Z22000RL
User Capacity: 120*034*123*776 bytes [120 GB]
Sector Size: 512 bytes logical/physical
Rotation Rate: Solid State Device
Form Factor: 1.8 inches
Device is: In smartctl database [for details use: -P show]
ATA Version is: ACS-2 T13/2015-D revision 3
SATA Version is: SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is: Wed Nov 21 10:00:41 2018 RTZ
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status: (0x05) Offline data collection activity
was aborted by an interrupting command from host.
Auto Offline Data Collection: Disabled.
Self-test execution status: ( 25) The self-test routine was aborted by
the host.
Total time to complete Offline
data collection: ( 0) seconds.
Offline data collection
capabilities: (0x71) SMART execute Offline immediate.
No Auto Offline data collection support.
Suspend Offline collection upon new
command.
No Offline surface scan supported.
Self-test supported.
Conveyance Self-test supported.
Selective Self-test supported.
SMART capabilities: (0x0002) Does not save SMART data before
entering power-saving mode.
Supports SMART auto save timer.
Error logging capability: (0x01) Error logging supported.
General Purpose Logging supported.
Short self-test routine
recommended polling time: ( 2) minutes.
Extended self-test routine
recommended polling time: ( 10) minutes.
Conveyance self-test routine
recommended polling time: ( 2) minutes.

SMART Attributes Data Structure revision number: 1
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
5 Retired_Block_Count 0x0032 100 100 000 Old_age Always - 0
9 Power_On_Hours_and_Msec 0x0032 139 100 000 Old_age Always - 4235h+00m+00.000s
12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 215
166 Unknown_Attribute 0x0032 100 100 000 Old_age Always - 5366
167 Unknown_Attribute 0x0032 100 100 000 Old_age Always - 0
168 Unknown_Attribute 0x0032 100 100 000 Old_age Always - 5418
169 Unknown_Attribute 0x0032 100 100 000 Old_age Always - 17
170 Reserve_Block_Count 0x0032 100 100 000 Old_age Always - 0
171 Program_Fail_Count 0x0032 100 100 000 Old_age Always - 0
172 Erase_Fail_Count 0x0032 100 100 000 Old_age Always - 0
173 Unknown_SandForce_Attr 0x0032 100 100 --- Old_age Always - 5380
174 Unexpect_Power_Loss_Ct 0x0032 100 100 000 Old_age Always - 48
187 Reported_Uncorrect 0x0032 100 100 000 Old_age Always - 0
194 Temperature_Celsius 0x0022 070 100 000 Old_age Always - 30 (Min/Max 0/50)
199 SATA_CRC_Error_Count 0x0032 100 100 000 Old_age Always - 1
230 Life_Curve_Status 0x0032 100 100 000 Old_age Always - 180
232 Available_Reservd_Space 0x0033 100 100 004 Pre-fail Always - 100
233 SandForce_Internal 0x0032 100 100 000 Old_age Always - 500400
241 Lifetime_Writes_GiB 0x0030 253 253 000 Old_age Offline - 66289
242 Lifetime_Reads_GiB 0x0030 253 253 000 Old_age Offline - 8355

SMART Error Log Version: 1
No Errors Logged

SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Abort offline test Aborted by host 90% 126 -

SMART Selective self-test log data structure revision number 1
SPAN MIN_LBA MAX_LBA CURRENT_TEST_STATUS
1 0 0 Not_testing
2 0 0 Not_testing
3 0 0 Not_testing
4 0 0 Not_testing
5 0 0 Not_testing
Selective self-test flags (0x0):
After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.

передать в переменную, чтобы скрипт не создавал дополнительные файлы, но раз это сложнореализуемо, сделаю вывод в файл и буду его парсить, чтобы взять с него нужные мне атрибуты.
Если такой вариант не разрешат - попробую сразу вывод парсить, чтобы из него сразу получить нужные мне атрибуты: 9, 194, 199, 241.

Отправлено: 10:23, 21-11-2018 | #6


Аватара для CyberDaemon

DOOMer


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

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


Цитата densan:
сразу вывод парсить »
Если под винду есть smartctl, может и grep найдется?

-------
"640 K ought to be enough for anybody" Bill Gates, 1981


Отправлено: 12:16, 21-11-2018 | #7


Пользователь


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

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


grep можно сделать через findstr

Отправлено: 12:25, 21-11-2018 | #8


Аватара для CyberDaemon

DOOMer


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

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


А может, тогда еще аналоги sed и cut найдутся?
Код: Выделить весь код
RAW_PON=$(smartctl -A /dev/sda | grep Power_On_Hours_and_Msec | sed 's/\ \{1,\}/\t/g' | cut -f 11)
RAW_TC=$(smartctl -A /dev/sda | grep Temperature_Celsius | sed 's/\ \{1,\}/\t/g' | cut -f 10)
RAW_LWG=$(smartctl -A /dev/sda | grep Lifetime_Writes_GiB  | sed 's/\ \{1,\}/\t/g' | cut -f 10)
дергаем smartctl (можно с ключом -A, чтобы выводил только аттрибуты), grep'ом выбираем строку с интересующим атрибутом, sed'ом заменяем все подряд-идущие-пробелы табуляцией, cut'ом выдергиваем нужно поле, результат в переменную. Повторить нужное количество раз.

-------
"640 K ought to be enough for anybody" Bill Gates, 1981


Отправлено: 13:03, 21-11-2018 | #9


Ветеран


Contributor


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

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


Вот вариант с обработкой текстового файла выдачи Вашей программы (для отладки взял из Вашего поста)
Код: Выделить весь код
@Echo Off
cls
	Set "Param=9 194 199 241"
	FOR /F "usebackq tokens=1,2* delims= " %%i IN (`more "Z:\Soft_In\smartctl.txt"`) DO (
		If /I "%%i %%j"=="SMART Error" GoTo :Continue
		For %%p In (%Param%) Do If /I "%%p"=="%%i" Set "Param%%i=%%j %%k" &Set "Str%%i=%%i %%j %%k")
	)
	:Continue

Echo "%Str9%"
Echo   "%Param9%"
Echo:
Echo "%Str194%"
Echo     "%Param194%"
Echo:
Echo "%Str199%"
Echo     "%Param199%"
Echo:
Echo "%Str241%"
Echo     "%Param241%"

pause
Но этого делать не надо. Однозначно надо сразу обрабатывать вывод программы, для чего в For заменить:

(`more "Z:\Soft_In\smartctl.txt"`)
(`c:\Temp\smart\smartctl.exe -a /dev/sda`)

Естественно, не проверялось.

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 21-11-2018 в 13:38.


Отправлено: 13:29, 21-11-2018 | #10



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

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

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - [решено] Как записать в переменную результат выполнения команды? MSI Скриптовые языки администрирования Windows 64 24-12-2020 18:20
CMD/BAT - результат команды в переменную BreakHeart Скриптовые языки администрирования Windows 13 26-06-2019 00:15
CMD/BAT - Результат выполнения команды в переменные DRON4eg Скриптовые языки администрирования Windows 2 19-05-2017 08:59
CMD/BAT - Результат выполнения команды дописать в файл в определенную строку DR_WELL Скриптовые языки администрирования Windows 1 24-06-2011 04:57
CMD/BAT - [решено] Строка результат выполнения filever.exe передать в переменную dARKest Скриптовые языки администрирования Windows 3 07-09-2009 22:50




 
Переход