Войти

Показать полную графическую версию : Результат выполнения команды в переменную


densan
20-11-2018, 13:54
Здравствуйте.

Есть задача получить скриптом некоторые 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
20-11-2018, 14:20
работает как при запуске без параметров, потому что параметров как бы и нет, они в кавычках не воспринимаются.
весь вывод загнать в переменную не получится, разве что одну строку из вывода.
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%

megaloman
20-11-2018, 15:16
На выходе этой команды будет много строк, хочу весь вывод загнать в переменную, которую буду парсить и выбирать нужные значения.
Не получается вывод команды передать в переменную »весь вывод загнать в переменную не получится »Можно загнать не в одну переменную, а во множество, например, переменных с номерами в именах. У меня нет Вашей программы 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Но, возможно, при этом получим очень длинную строку и получим ошибку и радость от такой строки очень сомнительна - её обработать гораздо труднее, чем в предыдущем случае.

alpap
20-11-2018, 18:35
которую буду парсить и выбирать нужные значения »
вот тут подробнее
согласен с 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

Iska
20-11-2018, 19:38
Если нужен весь вывод с последующим парсингом — я бы вообще работал с 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 вывод как душеньке будет угодно, в том числе и регулярками.

densan
21-11-2018, 10:23
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.

CyberDaemon
21-11-2018, 12:16
сразу вывод парсить »
Если под винду есть smartctl, может и grep найдется?

densan
21-11-2018, 12:25
grep можно сделать через findstr

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

megaloman
21-11-2018, 13:29
Вот вариант с обработкой текстового файла выдачи Вашей программы (для отладки взял из Вашего поста)@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`)

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

alpap
21-11-2018, 14:38
@echo off
:: ----------------------------------------------------------------------
:: Заменить: more "C:\file.txt" на C:\Temp\smart\smartctl.exe -a /dev/sda
:: ----------------------------------------------------------------------
:: Просто вывод на экран нужных строк
:: for /f "delims=" %%a in ('more "C:\file.txt"^|findstr /lb /c:"9" /c:"194" /c:"199" /c:"241"') do echo %%a
:: Вывод в переменные, а потом на экран
for /f "tokens=1* delims=[]" %%a in ('more "C:\file.txt"^|findstr /lb /c:"9" /c:"194" /c:"199" /c:"241"^|find /n /v ""') do set "v%%a=%%b"
echo %v1%
echo %v2%
echo %v3%
echo %v4%
pause

Iska
21-11-2018, 18:36
Скрипт будет запускаться в ограниченной среде, где WSH/PoSH запрещен или отсутствует. »
Э… WinPE?

densan
22-11-2018, 16:23
Э… WinPE? »
Нет. Критичные ПК где ИБ закрутило гайки по самое небалуйся.

Iska
22-11-2018, 17:38
Критичные ПК где ИБ закрутило гайки по самое небалуйся. »
:). А с mhsta.exe дело как обстоит? Тоже под запретом, або нет?




© OSzone.net 2001-2012