cron вызывает bash-скрипт, который вызывает «script» для запуска программы на python. Следующая строка bash-скрипта выполняется немедленно, перед завершением script / python

#python #linux #bash #cron

#python #linux #bash #cron

Вопрос:

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

Я убежден, что cron здесь каким-то образом виноват, но ради аргументации, вот фиктивный bash-скрипт (очевидно, это просто иллюстрация. В реальном мире я выполняю некоторую работу в программе на Python, а затем пытаюсь скопировать ее рабочий продукт в другое место после того, как это будет сделано.):

 #!/usr/bin/env bash

cd /tmp/kier/script
script output -c "./sleeper.py; echo '...and we are done'"
echo "This is the next line after invoking script..."
  

… и для полноты картины, вот python-скрипт, sleeper.py:

 #!/usr/bin/env python3

import time

print("python program starting")
time.sleep(5)
print("python program done")
  

Когда я запускаю bash-скрипт из командной строки, все хорошо. В частности, текст «Это следующая строка …» печатается в самом конце, после 5-секундного ожидания.

Но когда я запускаю его из cron, вывод приходит в неправильном порядке (это электронное письмо, которое приходит ко мне после того, как cron запускает задание):

 Script started, file is output
Script done, file is output
This is the next line after invoking script...
python program starting
python program done
...and we are done
Script started, file is output
  

Таким образом, вы можете видеть, что «Это следующая строка …» печатается еще до того, как скрипт python действительно запустился. Как будто он запускает скрипт python в фоновом режиме или что-то в этом роде.

Я в тупике. Почему это происходит и как я могу заставить echo команду подождать, пока script не завершится запуск программы на python?

(Наконец, да, я мог бы включить свою дополнительную команду в команды, которые я отправляю script , и я действительно рассматриваю это. Но давай! Это безумие!)

Комментарии:

1. Я не воспроизвожу это (в Ubuntu). Проверил почту из задания cron, и для меня строки находятся в том же порядке, что и при интерактивном запуске. В ваших результатах, отправленных по электронной почте, есть что-то очень странное, не в последнюю очередь то, что строка Script started, file is output повторяется (один раз в начале и один раз в конце).

2. что "./sleeper.py; echo '...and we are done'" в вашем примере? Вы запускаете что-то еще с threading ? Вы использовали join() для ожидания окончания потока?

3. Согласен, @alaniwi, странно, что строка «Скрипт запущен …» повторяется в выводе электронного письма. И это в окне RedHat. Мне не приходило в голову, что это может зависеть от операционной системы. Я могу попытаться исследовать это. Спасибо.

4. Извините, @furas, я изменил приведенный выше текст, чтобы объяснить, что «python script», который я цитирую, является «sleeper.py.» Я надеюсь, что это проясняет ситуацию. Я не использую join() выше, но я попробовал это, когда впервые столкнулся с этой проблемой, и это не помогло. И нет потоков; приведенный выше пример завершен и ведет себя так, как я описал (в моем окне RedHat).

Ответ №1:

Я должен продолжить и поделиться решением, которое я придумал. В итоге я так и не получил вразумительного ответа на вопрос, ПОЧЕМУ он ведет себя таким образом в моей среде (RedHat), поэтому я остановился на обходном пути. Я…

  • создан файл sentinel перед вызовом «script»,
  • включена дополнительная команда, удаляющая файл sentinel в тексте команды скрипта, а затем
  • дождался удаления файла sentinel, прежде чем продолжить.

Вот так:

 sentinel=`mktemp`
script output -c "./sleeper.py; rm $sentinel"
while [ -f $sentinel ]
do
    sleep 3
done
  

Да, это взлом, но мне нужно было двигаться дальше.