Работы в ударе, вероятно, в других оболочках. Поместите в Вашем .bashrc
function rm() {
while test "${1:0:1}" = "-"; do
shift
done
if test $# -eq 1; then
command rm "$1"
else
command rm -i "$@"
fi
}
Я Определенно предпочитаю решение для РЕДАКТИРОВАНИЯ № 3 (см. рев).
если не в той же оболочке используют некоторое время цикл с условием на PS-p возвращающий true. Поместите сон в цикл для сокращения использования процессора.
while ps -p <pid> >/dev/null 2>&1
do
sleep 10
done
или если Ваш UNIX поддерживает/proc (например, HP-UX все еще не делает).
while [[ -d /proc/<pid> ]]
do
sleep 10
done
Если Вы хотите тайм-аут
timeout=6 # timeout after 1mn
while ((timeout > 0)) && ps -p <pid> >/dev/null 2>&1
do
sleep 10
((timeout -= 1))
done
Существует другой путь: не используйте крон. Используйте пакетную команду для укладки заданий.
Например, Вы могли ежедневные стеки все Ваши задания. Пакет может быть настроен для разрешения некоторого параллелизма, таким образом, заблокированное задание не будет останавливать весь стек (Это зависит от операционной системы).
Создайте FIFO в своем корневом каталоге:
$ mkfifo ~/tata
в конце Вашего задания:
echo "it's done" > ~/tata
в начале другого задания (тот, который ожидает):
cat ~/tata
Это не опрашивает его, старое хорошее блокирование IO.
Используя сигналы:
При начинании сценария (сценариев), кто, ожидают:
echo $$ >>~/WeAreStopped
kill -STOP $$
в конце Вашего долгого задания:
if [[ -f ~/WeAreStopped ]] ; then
xargs kill -CONT < ~/WeAreStopped
rm ~/WeAreStopped
fi
Можно изменить задание крона для использования некоторого флага.
Вместо
2 2 * * * /path/my_binary
Можно использовать
2 2 * * * touch /tmp/i_m_running; /path/my_binary; rm /tmp/i_m_running
И просто контролируйте этот файл в сценарии или даже вручную. Если это существует, то Ваша программа работает; иначе не стесняйтесь делать независимо от того, что Вы хотите.
Образец сценария:
while [[ -f /tmp/i_m_running ]] ; do
sleep 10 ;
done
launch_whatever_you_want
В случае, если Вам не нравится использовать sleep
, можно изменить сценарий и выполнить его через крон однажды в X минут.
В этом случае образец сценария будет:
[[ -f /tmp/i_m_running ]] && { echo "Too early" ; exit ; }
launch_whatever_you_want
Этот путь немного легче, поскольку Вы не должны находить PID своего процесса крона.
Нет никакого средства для процесса для ожидания другого процесса для окончания, за исключением родителя для ожидания одного из его дочерних процессов для окончания. Если Вы можете, запустить программу через сценарий:
do_large_amount_of_work
start_interactive_program
Если Вы не можете сделать этого, например, прежде чем Вы захотите запустить большой объем работы с задания крона, но интерактивную программу от контекста Вашей сессии, то сделайте это
do_large_amount_of_work
notify_completion
Существует несколько способов реализовать notify_completion
. Некоторые настольные среды обеспечивают, механизм уведомления (Откройте окно на удаленном X дисплеев (почему "Не может открыть дисплей")? может быть полезным). Можно также заставить один файл использования изменить уведомления. На Linux средство уведомления об изменении файла является inotify.
do_large_amount_of_work
echo $? >/path/to/finished.stamp
Реагировать на создание /path/to/finished.stamp
:
inotifywait -e close_write -q /path/to/finished.stamp
start_interactive_program
Если Вы не можете изменить путь do_large_amount_of_work
вызывается, но Вы знаете, какой файл это изменяет в последний раз, можно использовать тот же механизм для реакции, когда тот файл закрывается. Можно также реагировать на другие события, такие как переименование файла (см. inotifywait
руководство для списка возможностей).
Пусть скрипт, запускаемый cronjob, вызывает пустой сценарий оболочки, в который вы можете вставлять последующие -задачи, если они вам нужны.
Это очень похоже на подход Жиля.
cronjob-task.sh
содержит:
# do_large_amount_of_work
./post-execute.sh
где post-execute.sh
обычно пусто, если вы не видите, что вам нужно запустить последующую задачу -.