Скрипт работает из терминала: воспроизводим минимальное окружение через env -i

Из терминала отчёт собирается, а из планировщика команда обработки не находится. Проверка начинается с версии программы, затем с прав, хотя самая частая разница лежит раньше: интерактивная оболочка подготовила PATH и несколько переменных, которых в задании нет. Чтобы не гадать, полезно повторить запуск с минимальным окружением.

env -i запускает команду без унаследованного набора переменных. Затем можно добавить ровно те значения, которые входят в контракт скрипта. Это диагностический опыт: он показывает, какие зависимости скрывались в вашей сессии. Сам по себе минимальный набор не делает программу безопасной и не ограничивает её доступ к файлам.

Подготовим контролируемую проверку

Пример создаёт отдельный check-env.sh. Он выводит только несекретные настройки и проверяет наличие awk. Абсолютные пути /usr/bin и /bin подходят для типичного Linux и Git Bash, но в другой системе их нужно сверить.

cat > check-env.sh <<'SH'
#!/bin/sh
printf 'MODE=%s\n' "${MODE-unset}"
printf 'PATH=%s\n' "$PATH"
command -v awk || exit 1
SH
env -i PATH=/usr/bin:/bin MODE=batch /bin/sh ./check-env.sh

Вы увидите MODE=batch, заданный PATH и путь к awk. Имя /bin/sh указано полностью: для его поиска не нужна ещё не подготовленная переменная PATH. Запуск через sh также не требует исполняемого бита у созданного учебного файла.

Теперь уберите MODE из команды запуска. Скрипт покажет unset. Если рабочая программа зависела от этого значения, станет ясно, что настройку нужно передавать явно. Убирать PATH как эксперимент тоже можно, но некоторые оболочки устанавливают собственный путь по умолчанию. Поэтому «переменной не было» и «поиск программ точно невозможен» — разные утверждения.

Окружение не задаёт рабочий каталог

env -i очищает переменные, но текущая папка остаётся прежней. Скрипт, который открывает ./config.ini, всё ещё зависит от места запуска. Чтобы найти такую зависимость, повторите проверку из другого каталога, передав абсолютный путь к самому скрипту. Если конфиг должен лежать рядом с программой, вычислите его путь явно либо принимайте его обязательным аргументом.

Точно так же остаются открытые файловые дескрипторы, пользователь процесса и доступные ресурсы. Это объясняет, почему успешный тест с env -i не является полной копией планировщика. Он изолирует одну конкретную переменную опыта — наследование окружения — и позволяет двигаться дальше по фактам.

Не печатайте весь env в общий CI-лог. Среди переменных могут находиться токены и служебные учётные данные. Для диагностики называйте конкретные настройки и показывайте только те значения, которые допустимо раскрывать. Для секрета обычно достаточно признака «передан/не передан».

Закрепим обнаруженный контракт

После опыта разделите настройки на обязательные и имеющие осмысленный default. Обязательные проверяйте до запуска работы. PATH задавайте так, чтобы он содержал только ожидаемые каталоги, либо используйте известные абсолютные пути для критичных программ. Не добавляйте текущий каталог в PATH только ради исчезновения ошибки: это создаёт новую зависимость от содержимого папки запуска.

Не подключайте целиком интерактивный .bashrc в пакетный скрипт. Там могут быть приглашения, aliases и команды, рассчитанные на терминал. Лучше вынести нужную несекретную конфигурацию в явный файл формата, который скрипт умеет читать, либо передавать её через настройки задания.

В программе Linux и Bash автоматизация повторяемых операций связана с настройкой окружения и диагностикой. Откройте программу и продолжите от локального запуска к скрипту, который одинаково объяснимо работает из терминала, расписания и среды сборки.

Ещё по теме

Продолжить на практике

  • Linux и Bash для DevOps-инженеров ↗

    Linux для работы с серверами: процессы, права, systemd, сеть, диски и логи. Автоматизируйте повседневные задачи на Bash и разберите типичные сбои сервиса — от занятого порта до переполненного диска.