3

У меня есть относительно простой bash-скрипт, который отлично работает при прямом вызове, но не работает при запуске cron. Почему это не удается и как я могу заставить его работать через cron?

#!/bin/bash
apt-get update -y
apt-get upgrade -y
apt-get install boinc-client -y

Как только cron попытается запустить его, ручной вызов приведет к этой ошибке:

dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.

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

3 ответа3

5

Обычный ответ на этот тип вопросов заключается в том, что задания cron выполняются в неинтерактивных оболочках, не относящихся к входу в систему, поэтому большинство файлов запуска вашей оболочки (как общесистемные файлы в /etc и ваши личные точечные файлы в вашем домашнем каталоге) не являются Источник (чтение и выполнение), потому что большинство файлов запуска оболочки применяются к оболочкам входа в систему (первая оболочка, которую вы видите при входе в компьютер) или к интерактивным оболочкам (оболочки, которые подключаются к терминалам, сеансам ssh или эмуляторам терминалов, поскольку пользователь взаимодействует с ними через указанный терминал).

Поэтому, если вы поместите команду в задание cron, которое на самом деле зависит от некоторых настроек среды (включая изменения PATH ), которые обычно происходят в таких местах, как /etc/profile , /etc/bashrc , ~/.profile или ~/.bashrc , это установка не произойдет для работы cron. Формат файла cron позволяет вам указывать переменные среды для ваших заданий, поэтому вы можете указать BASH_ENV или ENV чтобы указывать его на сценарий запуска оболочки для источника. Смотрите раздел "Invocation" на справочной странице bash(1) .

1

Удалось решить это практически без понимания того, что происходит. Оказалось, что, хотя я запускался из корневого crontab, командам apt-get по-прежнему требовался sudo перед ними. Логично, что я ожидал, что в этом нет необходимости, так как скрипт уже выполнялся "как root", но как только я добавил sudo ... все работало точно так, как ожидалось.

1

Это не квалифицируется как ответ, но я не могу комментировать. Предложения:

  1. добавьте следующее к вашему bash-скрипту. Последняя строка, занесенная в почтовый вывод, будет ошибочной командой.

    set -x
    set -e
    
    • убедитесь, что у вас есть sendmail (установите пакет, такой как postfix или esmtp)
    • установить почтовый ридер (рекомендую mutt)
    • убедитесь, что почта достигает вас
      • через postfix (может быть сделано установщиком автоматически): добавьте root: my-user-name в /etc/aliases или /etc/postfix/aliases
      • через cron: добавьте MAILTO="my-user-name" в соответствующий файл crontab
  2. Убедитесь, что скрипт будет работать в другой среде. Укажите полный путь к apt-get (вероятно, не виновник, так как известно, что apt-get был найден) и запустите его в консоли (не в терминале) вне X. (для некоторых сценариев dpkg configure требуется сеанс X).

    • измените скрипт, чтобы использовать абсолютные пути, например /usr/bin/apt-get update -y (замените на правильный путь)
    • переключиться на консоль нажатием ctrl-alt-f1
    • переключиться на пользователя root: sudo -i
    • запустить оболочку без входа в систему без среды: env -i /bin/bash --noprofile --norc (заменить на правильный путь)
    • запустите скрипт: /my/full/path/to/cronscript . Это работает?
  3. Есть ли у сценария разрешение? Вы используете системный crontab? (еще раз, вероятно, не виновник)

    • Вы заявили, что используете системный crontab, так что пропустите это.
  4. Apt-get требует поддержки сеанса (consolekit или systemd). Однако это всего лишь выстрел в темноте.

    • Не знаю достаточно, чтобы помочь.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .