База знаний Зодиак.АйТиЭм

Результат исполнения скрипта

Доставка результатов исполнения скрипта с агентов на сервер

Результат исполнения скрипта

Код возврата является универсальным механизмом сигнализации об успехе/неуспехе исполнения скрипта и анализируется для скриптов на всех поддерживаемых языках: 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.

Во всех приведенных примерах при оформлении таких скриптов в веб-консоли Зодиак.АйТиЭм необходимо при включении настройки "Результат" завести все свойства, которые необходимо доставлять на сервер.

script_return1.png
script_return2.png

Для Python (через использовании шебанга в директиве Shell-скрипт)

Данный язык является кроссплатформенным и часто используется, например, для написания скриптов дополнительной инвентаризации на ОС семейства Linux. В «Зодиак.АйТиЭм» Python-скрипты можно выполнять при использовании соответствующего шебанга: #!/usr/bin/env python3 и при условии, что на целевой клиентской машине (где установлен агент) есть интерпретатор Python. Агент «Зодиак.АйТиЭм» исполняет Python-скрипт как обычный процесс и анализирует его вывод. Поскольку Python в контексте агента не возвращает типизированный объект, а печатает текст в STDOUT, для него применяются те же правила, что и для SH/BASH, подробно описанные в главе выше.

Правило возврата данных: скрипт должен напечатать данные, которые он хочет вернуть, в STDOUT в ENV-формате (пары КЛЮЧ=ЗНАЧЕНИЕ, каждая с новой строки). Пустые строки служат разделителями между несколькими объектами (записями).

Для сигнализации об успешном или неуспешном завершении скрипта используется код возврата (sys.exit()):
• 0 — скрипт выполнился успешно, данные в STDOUT корректны.
• 1 или любое другое число — произошла ошибка.
Эта информация затем отображается в разделе Статистика исполнения скрипта

2026-04-02_16-09-44.png

Пример: Получение информации о каждом ядре процессора (множество объектов)

Этот скрипт собирает частоту для каждого ядра процессора и создаёт отдельный объект для каждого ядра. Пустая строка между блоками данных служит разделителем объектов.

Следующий скрипт собирает базовую информацию об ОС и выводит её в виде одного объекта.

#!/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.

После доставки на сервер для этого компьютера будут сформированы четыре строки во вкладке Результаты с указанными колонками:
2026-04-02_16-37-11.png

• Все напечатанные объекты должны иметь одинаковый набор свойств (одинаковые ключи). В примере выше каждый объект содержит ключи 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()
}

Во всех приведенных примерах при оформлении таких скриптов в веб-консоли Зодиак.АйТиЭм необходимо при включении настройки "Результат" завести все свойства, которые необходимо доставлять на сервер.