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

Ответить
 • Просмотры: 1
Аватара пользователя
densan

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

Сообщение densan »

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



Есть задача получить скриптом некоторые 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 без параметров.

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

Прошу совета.
Аватара пользователя
Elven

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

Сообщение Elven »

работает как при запуске без параметров, потому что параметров как бы и нет, они в кавычках не воспринимаются.

весь вывод загнать в переменную не получится, разве что одну строку из вывода.



Код:

Код: Выделить всё

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%
Аватара пользователя
alpap

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

Сообщение alpap »

Цитата densan:



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

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





Цитата Elven:



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




Можно загнать не в одну переменную, а во множество, например, переменных с номерами в именах. У меня нет Вашей программы 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

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

Сообщение megaloman »

Цитата densan:



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




вот тут подробнее

согласен с 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
Аватара пользователя
alpap

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

Сообщение alpap »

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



Скрытый текст

[spoiler]Код:
[/spoiler]

Код: Выделить всё

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 вывод как душеньке будет угодно, в том числе и регулярками.
Аватара пользователя
Iska

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

Сообщение Iska »

Цитата Iska:



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




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



Задача: посредством Smartmontools снять смарт атрибуты и передать их в ПО мониторинга. Хотелось бы вывод



Код:

Код: Выделить всё

c:\Temp\smart\smartctl.exe -a /dev/sda




Скрытый текст

[spoiler]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.[/spoiler]




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

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

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

Сообщение densan »

Цитата densan:



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




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

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

Сообщение densan »

А может, тогда еще аналоги 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'ом выдергиваем нужно поле, результат в переменную. Повторить нужное количество раз.
Ответить

Вернуться в «Скриптовые языки администрирования Windows»