Результат исполнения скрипта
Доставка результатов исполнения скрипта с агентов на сервер
Результат исполнения скрипта
Код возврата является универсальным механизмом сигнализации об успехе/неуспехе исполнения скрипта и анализируется для скриптов на всех поддерживаемых языках: JavaScript, CoffeeScript, PowerShell, SH/BASH. Анализ происходит по стандартному принципу: код возврата 0 соответствует успешному завершению скрипта, любой код кроме 0 - неуспешному. Для доставки результатов такого анализа с агентов на сервер необходимо включить переключатель "Статистика". Собираемая статистика для каждого агента состоит из 4 полей: кол-во успешных запусков, кол-во неуспешных запусков, дата/время последнего успешного запуска, дата/время последнего неуспешного запуска.
Анализ результата исполнения скрипта происходит по-разному для разных языков. Для каждого языка существует бесконечное множество вариантов, как скрипт на этом языке может вернуть данные: напечатать в виде текста на русском/английском/других языках, напечатать в виде XML/JSON, вернуть типизированный объект(ы), создать файл и другие. Разумеется, агент Зодиак.АйТиЭм не может автоматически распознать результат и вывод любого скрипта. Для каждого языка существуют правила возврата данных, которые агент сможет распознать. Мы постарались выбрать такие правила, которые покрывают наиболее распространенные сценарии на каждом языке.
Для SH/BASH:
Поскольку данный язык не поддерживает типизацию и оперирует текстовыми данными, получаемыми из вывода процессов, то и агент Зодиак.АйТиЭм анализирует текстовый вывод (STDOUT) таких скриптов. Правило возврата данных из таких скриптов следующее: скрипт должен напечатать данные, которые он хочет вернуть в так называемом ENV-формате. Это один из самых распространенных форматов вывода и файлов в ОС семейства Linux.
ENV-формат (или формат переменных окружения) — это простой текстовый формат, в котором данные представлены в виде пар КЛЮЧ=ЗНАЧЕНИЕ, каждая с новой строки.
Структура формата
КЛЮЧ1=значение1
КЛЮЧ2=значение2
КЛЮЧ3=значение3
Рекомендации
• Каждая пара на отдельной строке
• Ключ и значение разделены символом=
• Пробелы вокруг=обычно не ставятся, но допустимы
• Значения могут быть в кавычках (особенно если содержат пробелы или спецсимволы)
• Пустые строки используются как разделители между наборами данных (объектами)
Примеры ENV-формата
Файл /etc/os-release (классический ENV-формат)
NAME="Astra Linux"
VERSION_ID="1.7"
ID=astra
HOME_URL="https://astralinux.ru"
Почему это называется ENV-формат
Потому что переменные окружения (environment variables) в Linux хранятся и передаются именно в таком формате:
• Файлы конфигурации (/etc/environment,/etc/os-release)
• Вывод команд (env,printenv)
• Файлы дляsystemd(EnvironmentFile)
• Конфигурации Docker (--env-file)
Пример 1 (файл /etc/os-release):
cat /etc/os-release
Вывод скрипта для примера 1:
PRETTY_NAME="Astra Linux"
NAME="Astra Linux"
ID=astra
ID_LIKE=debian
ANSI_COLOR="1;31"
HOME_URL="https://astralinux.ru"
SUPPORT_URL="https://astralinux.ru/support"
LOGO=astra
VERSION_ID=1.7_x86-64
VERSION_CODENAME=1.7_x86-64
Пример 1 соответствует возврату одного объекта со свойствами: PRETTY_NAME, NAME, ID, ID_LIKE, ...
После доставки таких данных на сервер для этого агента будет сформирована одна строка в таблице БД с колонками PRETTY_NAME, NAME, ID, ID_LIKE.
Пример 2 (файл /proc/cpuinfo):
cat /proc/cpuinfo
Вывод скрипта для примера 2:
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 167
model name : 11th Gen Intel(R) Core(TM) i5-11400F @ 2.60GHz
stepping : 1
cpu MHz : 2592.002
cache size : 12288 KB
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 167
model name : 11th Gen Intel(R) Core(TM) i5-11400F @ 2.60GHz
stepping : 1
cpu MHz : 2592.002
cache size : 12288 KB
Пример 2 соответствует возврату двух объектов со свойствами: processor, vendor_id, cpu family, ...
После доставки таких данных на сервер для этого агента будет сформированы две строки в таблице БД с колонками processor, vendor_id, cpu family, ...
Начало следующего объекта маркируется пустой строкой.
Все напечатанные таким образом объекты должны иметь одинаковый набор свойств.
Пример 3 (свои данные):
echo "kernel : $(uname -r)"
Вывод скрипта для примера 3:
kernel : 5.15.0-70-generic
Пример 3 соответствует возврату одного объекта с единственным свойством kernel.
Во всех приведенных примерах при оформлении таких скриптов в веб-консоли Зодиак.АйТиЭм необходимо при включении настройки "Результат" завести все свойства, которые необходимо доставлять на сервер.


Для Python (через использовании шебанга в директиве Shell-скрипт)
Данный язык является кроссплатформенным и часто используется, например, для написания скриптов дополнительной инвентаризации на ОС семейства Linux. В «Зодиак.АйТиЭм» Python-скрипты можно выполнять при использовании соответствующего шебанга: #!/usr/bin/env python3 и при условии, что на целевой клиентской машине (где установлен агент) есть интерпретатор Python. Агент «Зодиак.АйТиЭм» исполняет Python-скрипт как обычный процесс и анализирует его вывод. Поскольку Python в контексте агента не возвращает типизированный объект, а печатает текст в STDOUT, для него применяются те же правила, что и для SH/BASH, подробно описанные в главе выше.
Правило возврата данных: скрипт должен напечатать данные, которые он хочет вернуть, в STDOUT в ENV-формате (пары КЛЮЧ=ЗНАЧЕНИЕ, каждая с новой строки). Пустые строки служат разделителями между несколькими объектами (записями).
Для сигнализации об успешном или неуспешном завершении скрипта используется код возврата (
sys.exit()):
•0— скрипт выполнился успешно, данные вSTDOUTкорректны.
•1или любое другое число — произошла ошибка.
Эта информация затем отображается в разделеСтатистикаисполнения скрипта

Пример: Получение информации о каждом ядре процессора (множество объектов)
Этот скрипт собирает частоту для каждого ядра процессора и создаёт отдельный объект для каждого ядра. Пустая строка между блоками данных служит разделителем объектов.
Следующий скрипт собирает базовую информацию об ОС и выводит её в виде одного объекта.
#!/usr/bin/env python3
import psutil
import sys
def get_cpu_info():
try:
cpus = psutil.cpu_freq(percpu=True)
if not cpus:
print("CPU_INFO_ERROR=percpu вернул пустой список")
sys.exit(1)
for i, cpu in enumerate(cpus):
if i > 0:
print() # Пустая строка — разделитель объектов
# Безопасное форматирование значений
current = f"{cpu.current:.2f}" if cpu.current is not None else "N/A"
max_freq = f"{cpu.max:.2f}" if cpu.max is not None else "N/A"
print(f"CORE_NUMBER={i}")
print(f"CURRENT_FREQ_MHz={current}")
print(f"MAX_FREQ_MHz={max_freq}")
sys.exit(0)
except Exception as e:
print(f"CPU_SCRIPT_ERROR={str(e).replace('=', '_')}")
sys.exit(1)
if __name__ == "__main__":
get_cpu_info()
Вывод скрипта (STDOUT) для сервера с 4х-ядерным процессором:
CORE_NUMBER=0
CURRENT_FREQ_MHz=3192.03
MAX_FREQ_MHz=4800.00
CORE_NUMBER=1
CURRENT_FREQ_MHz=3192.03
MAX_FREQ_MHz=4800.00
CORE_NUMBER=2
CURRENT_FREQ_MHz=3192.03
MAX_FREQ_MHz=4800.00
CORE_NUMBER=3
CURRENT_FREQ_MHz=3192.03
MAX_FREQ_MHz=4800.00
Пример соответствует возврату четырех объектов со свойствами: CORE_NUMBER, CURRENT_FREQ_MHz, MAX_FREQ_MHz.
После доставки на сервер для этого компьютера будут сформированы четыре строки во вкладке Результаты с указанными колонками:

• Все напечатанные объекты должны иметь одинаковый набор свойств (одинаковые ключи). В примере выше каждый объект содержит ключи
CORE_NUMBER,CURRENT_FREQ_MHz,MAX_FREQ_MHz.• Если какое-то значение отсутствует (например,
cpu.maxвернулNone), рекомендуется выводить специальное значение (N/A).• При возникновении ошибки выведите в
STDOUTключ с понятным названием (например,SCRIPT_ERROR) и завершите скрипт с кодом1. Это позволит увидеть причину ошибки в пунктеРезультатыданной директивы.
Во всех приведенных примерах при оформлении таких скриптов в веб-консоли Зодиак.АйТиЭм необходимо при включении настройки "Результат" завести все свойства, которые необходимо доставлять на сервер.
Для PowerShell:
Данный язык поддерживает типизацию и вывод данных из скрипта в виде объектов, а не только в виде текста. Правило возврата данных из таких скриптов следующее: скрипт должен вернуть единственный PSObject, единственный HashTable, массив из PSObject или массив из HashTable.
Пример 1 (инвентаризация WMI):
Get-WmiObject -Class 'Win32_Service' -Namespace 'ROOT\CIMV2' -Property 'DisplayName','Name','Status'
Командлет Get-WmiObject возвращает данные в виде массива PSObject, что соответствует правилу возврата данных из скриптов PS1 агента Зодиак.АйТиЭм.
Поэтому дополнительных действий не требуется.
Пример 2 (версия ОС):
Get-ComputerInfo -Property "OsVersion"
Командлет Get-ComputerInfo возвращает данные в виде PSObject, что соответствует правилу возврата данных из скриптов PS1 агента Зодиак.АйТиЭм.
Поэтому дополнительных действий не требуется.
Этот командлет эквивалентен утилите systeminfo, но утилита systeminfo печатает данные в виде текста, что не соответствует правилу возврата данных из скриптов PS1 агента Зодиак.АйТиЭм.
Текстовый результат утилиты systeminfo тоже можно преобразовать в PSObject, но для этого требуется значительно более сложный скрипт:
$lines = @( systeminfo | findstr /C:"OS Version" /C:"Версия ОС" )
$result = @{}
$lines | % { if ($_.Contains(":")) { $parts = $_ -Split ":"; $result[$parts[0].Trim()] = $parts[1].Trim(); } }
if ($result["Версия ОС"] -ne $null) { $result["OS Version"] = $result["Версия ОС"]; }
$result
Поэтому в скриптах PowerShell мы рекомендуем пользоваться командлетами, чтобы избежать необходимости конвертации.
Во всех приведенных примерах при оформлении таких скриптов в веб-консоли Зодиак.АйТиЭм необходимо при включении настройки "Результат" завести все свойства, которые необходимо доставлять на сервер.
Для JavaScript/CoffeeScript:
Данный язык поддерживает типизацию и вывод данных из скрипта в виде объектов, а не только в виде текста. Правило возврата данных из таких скриптов следующее: скрипт должен вернуть единственный объект JavaScript или массив из объектов JavaScript.
Пример 1 (текущая дата/время):
return {
date: new Date()
}
Во всех приведенных примерах при оформлении таких скриптов в веб-консоли Зодиак.АйТиЭм необходимо при включении настройки "Результат" завести все свойства, которые необходимо доставлять на сервер.