Назад | Перейти на главную страницу

Запуск скрипта python в incrontab в Debian

У меня есть пользователь dropbox, который запускает демон Dropbox, я хочу отслеживать каталоги в каталоге Dropbox на предмет новых файлов и запускать скрипт python, когда они появляются.

У меня есть скрипт Python, который, как я знаю, работает:

$ /home/dropbox/monitor.py
Trying to get lock
Got lock, waiting for Dropbox to be idle
Dropbox idle
Finding instructions
Done, releasing lock

У меня есть запись incrontab:

$ incrontab -l
/home/dropbox/Dropbox IN_CREATE /home/dropbox/monitor.py | logger
/home/dropbox/test IN_CREATE logger "$$ $@ $# $% $&"

Когда я добавляю файл в тестовый каталог, я вижу результат в /var/log/syslog:

$ touch /home/dropbox/test/a
$ tail /var/log/syslog
...
Nov  9 10:18:27 vps incrond[1354]: (dropbox) CMD (logger "$ /home/dropbox/test a IN_CREATE 256")
Nov  9 10:18:27 vps logger: "$ /home/dropbox/test a IN_CREATE 256"
...

Однако, когда я добавляю файл в каталог Dropbox, команда не запускается:

$ touch /home/dropbox/Dropbox/a
$ tail /var/log/syslog
...
Nov  9 10:24:16 vps incrond[1354]: (dropbox) CMD (/home/dropbox/monitor.py | logger)
...

Таким образом, демон incron замечает новый файл и обнаруживает, что выполняется правильная команда, но на самом деле она никогда не выполняется. И сообщений об ошибках нет. Кажется, что incrontab можно использовать только для выполнения самых простых команд.

Это может быть вопрос, похожий на:

но я думаю, что у меня нет проблем с env, каждый путь абсолютен. Я пытался изменить .../monitor.py к /usr/bin/python2.7 .../monitor.py на всякий случай, но это не имело никакого значения.

редактировать

Деннис Карсемейкер предложил решение, согласно которому incrontab выполнял мою команду без использования cron, и это могло быть причиной проблемы. К сожалению, я все еще не могу заставить его работать.

Сначала я удалил лишнее из incrontab:

$ incrontab -l
/home/dropbox/Dropbox IN_CREATE /home/dropbox/monitor.py

Это должно запускать только мой файл монитора и не пытаться передавать что-либо в качестве аргументов. Нет кубиков, все равно нет выхода.

Затем я создал сценарий bash, содержащий инструкцию по выполнению моего сценария:

$ vim test.sh
logger "$PATH"
/usr/bin/python2.7 /home/dropbox/monitor.py | logger

Это дает следующий результат:

$ tail /var/log/syslog
Nov  9 23:50:28 vps incrond[1354]: (dropbox) CMD (/home/dropbox/test.sh)
Nov  9 23:50:28 vps logger: /usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin

Так что ничего из monitor.py, и мы видим, что каталог, содержащий python, находится в среде incrontab, поэтому нам даже не нужно указывать путь так же точно, как мы.

Я чувствую себя идиотом, заметив это.

Мой скрипт monitor.py пытается получить блокировку файла, прежде чем он начнет возиться с вещами Dropbox. В основном это делается для того, чтобы другие экземпляры monitor.py не вмешивались. Путь к заблокированному мной файлу не был абсолютным.

Итак, урок для всех, кто найдет эту страницу в будущем. Проверьте каждый путь, который вы используете, чтобы убедиться, что он 1) на пути 2) абсолютен.

Между cron и incron большая разница: в способе выполнения команд. Cron видит команду как один аргумент и вызывает оболочку для ее выполнения. Примерно так:

execvp('/bin/sh', ['/bin/sh', '-c', 'whatever is in the crontab']);

Итак, все конструкции оболочки, такие как && и | работай. Incron этого не делает, он анализирует саму команду и запускает ее напрямую. Итак, что incron работает в вашем случае:

execvp('/home/dropbox/monitor.py', ['/home/dropbox/monitor.py', '|', 'logger']);

Итак, ваш monitor.py запускается с | и logger как аргументы. Вы можете заключить свой сценарий в другой сценарий, который monitor.py | logger или используйте питон logging модуль для ведения журнала из самого monitor.py.