Советы по Linux: Управление длительностью выполнения запланированных заданий

Как остановить выполнение задания спустя определенное время

Допустим, вам нужно устранить назойливую. проблему, запустив отладку на 30 минут в полночь, или вы просто хотите использовать систему Linux в качестве будильника. Этот совет поможет вам остановить задания, запущенные с помощью cron и at, после того, как они проработают определенное время, или при выполнении каких-либо других условий. В этот совет теперь включена информация по команде timeout, входящей в состав пакета AppleTalk (Netatalk). -прим.ред.

Системы Linux® и UNIX® позволяют планировать выполнение заданий в будущем – однократно либо регулярно по расписанию. Читатели, ознакомившиеся с недавним советом, Планирование заданий с помощью cron и at, интересуются, как записывать телевизионные и радиопрограммы и останавливать запись по их окончании. Мне напомнили об итальянце Этторе Бугатти, который делал отличные автомобили в Эльзас-Лотарингии. Когда клиенты спрашивали его о том, почему он использует тормоза с тросовым приводом, тогда как другие автопроизводители перешли на гидравлику, Бугатти отвечал "Месье, я делаю автомобили для того, чтобы ездить, а не чтобы останавливаться". Этот совет рассказывает о том, как оснастить «тормозами» запланированные задания.

Вам нужны другие советы по Linux?

Посмотрите на советы, которые мы собрали для вас:

Не нашли то, чего искали? Проголосуйте за эту страницу и дайте нам знать об этом, и может быть, мы сможем сделать совет для вас!

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

Процесс таймера

Основным инструментом для работы со временем в сценариях командного процессора является команда sleep, которая приводит к остановке выполнения сценария на указанное время. По умолчанию время остановки задается в секундах, однако можно указывать значение времени с символами s, m или h для обозначения секунд, минут или часов соответственно. Эта команда приводит к остановке командного процессора, поэтому задание необходимо выполнять в другом командном процессоре, чего можно достичь, запустив задачу в фоновом режиме с помощью символа & .

Для начала предположим, что вы желаете запустить команду на 10 минут. В Листинге 1 показан сценарий bash, с помощью которого вы можете попробовать запустить команду xclock на указанный период времени. Попробуйте выполнить его в своей системе.

Listing 1. First attempt using runclock1.sh
#!/bin/bash
runtime=${1:-10m}
# Run xclock in background
xclock&
#Sleep for the specified time.
sleep $runtime
echo "All done"

Вы увидите часы, похожие на приведенные на Рисунке 1.

Рисунок 1. Обычные часы xclock
Обычные часы xclock

Единственная ошибка в таком подходе состоит в том, что сценарий остановился, но часы идут.


Родительские, дочерние и «осиротевшие» процессы

В Листинге 2 показан усовершенствованный сценарий runclock2.sh, который фиксирует определенную информацию об идентификаторах процессов командного процессора и xclock, а также результат работы сценария и результат выполнения команды ps, показывающий состояние процесса xclock после завершения выполнения командного процессора.

Listing 2. Gathering diagnostic information runclock2.sh
[ian@attic4 ~]$ cat runclock2.sh
#!/bin/bash
runtime=${1:-10m}
mypid=$$
# Run xclock in background
xclock&
clockpid=$!
echo "My PID=$mypid. Clock's PID=$clockpid"
ps -f $clockpid
#Sleep for the specified time.
sleep $runtime
echo "All done"
[ian@attic4 ~]$ ./runclock2.sh 10s
My PID=8619. Clock's PID=8620
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
ian       8620  8619  0 19:57 pts/1    S+     0:00 xclock
All done
[ian@attic4 ~]$ ps -f 8620
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
ian       8620     1  0 19:57 pts/1    S      0:00 xclock

Обратите внимание, что идентификатор родительского процесса (PPID) первого вызова ps - 8619, он же является идентификатором процесса (PID) сценария. После завершения работы сценария процесс часов становится «осиротевшим» и назначается дочерним процесса init— процесса 1. Дочерний процесс не завершается автоматически по завершении родительского процесса, хотя при выходе из системы завершение происходит.


Завершение дочернего процесса

Решением проблемы незавершенных дочерних процессов является их явное завершение с помощью команды kill. Она отправляет процессу сигнал , что обычно приводит к его завершению. Ниже вы увидите, как процесс может перехватывать сигналы и не завершаться, но здесь мы завершаем процесс часов с помощью сигнала прерывания (SIGINT).

Чтобы увидеть перечень сигналов, доступных в вашей системе, можно выполнить команду kill с параметром -l , как показано в Листинге 3. Обратите внимание, что некоторые сигналы являются общими для всех систем Linux, тогда как другие зависят от архитектуры определенной машины. Некоторые, например, ошибка при операциях с плавающей запятой (SIGFPE) или нарушение сегментации (SIGSEGV), формируются системой, тогда как другие, например, прерывание (SIGINT), сигналы пользователя (SIGUSR1 или SIGUSR2) или безусловное завершение (SIGKILL), могут посылаться приложениями.

Listing 3. Signals on a Fedora Core 5 system
[ian@attic4 ~]$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

Обратите внимание, что в Листинге 2 мы получали PID процесса xclock с помощью переменной командного процессора $! . В Листинге 4 показано, как использовать эту информацию для того, чтобы отправить сигнал завершения (SIGTERM) процессу xclock и завершить его.

Listing 4. Terminating the child process using runclock3.sh
[ian@attic4 ~]$ cat ./runclock3.sh
#!/bin/bash
runtime=${1:-10m}
mypid=$$
# Run xclock in background
xclock&
clockpid=$!
echo "My PID=$mypid. Clock's PID=$clockpid"
ps -f $clockpid
#Sleep for the specified time.
sleep $runtime
kill -s SIGTERM $clockpid
echo "All done"

В Листинге 5 показан результат выполнения runclock3.sh. Последняя команда kill подтверждает, что процесс xclock (PID 9285) действительно был завершен.

Listing 5. Verifying the termination of child processes
[ian@attic4 ~]$ ./runclock3.sh 5s
My PID=9284. Clock's PID=9285
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
ian       9285  9284  0 22:14 pts/1    S+     0:00 xclock
All done
[ian@attic4 ~]$ kill -0 9285
bash: kill: (9285) - No such process

Если вы опускаете указание сигнала, по умолчанию подается сигнал SIGTERM. Часть названия сигнала SIG необязательна. Вместо того чтобы использовать -s и указывать название сигнала, вы можете просто поставить - перед номером сигнала, поэтому все четыре формы завершения процесса 9285, показанные в Листинге 6, эквивалентны. Обратите внимание, что специальное значение -0, использованное в приведенном выше Листинге 4, проверяет, можно ли посылать сигналы процессу.

Listing 6. Ways to specify signals with the kill command
kill -s SIGTERM 9285
kill -s TERM 9285
kill -15 9285
kill 9285

Если вам просто нужен одноразовый таймер для управления приложением, как в предыдущем примере, можно использовать команду timeout, входящую в состав пакета сетевых утилит AppleTalk (Netatalk). Возможно, вам придется установить этот пакет (подробности можно найти ниже в разделе Ресурсы), поскольку в состав большинства сборок этот пакет не входит.


Другие условия завершения

Теперь у вас есть базовые инструменты, позволяющие запустить процесс на фиксированное время. Прежде чем углубляться в тему обработки сигналов, давайте рассмотрим, как работать с другими ситуациями, когда требуется завершение работы задачи - например, при периодической фиксации информации на протяжении конечного времени, которую необходимо завершить при достижении файлом определенного размера или когда в файле появится определенная строка. Такие задания лучше всего выполнять в цикле, например, с помощью for, while или until, при этом цикл выполняется периодически с определенной задержкой, реализуемой посредством команды sleep. Если вам нужно более точное указание времени (с точностью меньше секунды), можно использовать команду usleep.

Вы можете добавить к часам секундную стрелку и настроить цвета. Увидеть доступные названия цветов можно с помощью команды showrgb. Предположим, вы использовали команду xclock -bg Thistle -update 1& для запуска часов с секундной стрелкой и сиреневым фоном.

Теперь вы можете с помощью цикла фиксировать изображение часов каждую секунду, а затем собрать изображения в анимированный GIF. В Листинге 7 показано, как с помощью команды xwininfo найти идентификатор окна для команды xclock. После этого с помощью инструмента командной строки ImageMagick захватим 60 изображений часов с интервалом в одну секунду (подробную информацию об ImageMagick можно найти в разделе Ресурсы). Наконец, соберем изображения в бесконечно повторяющийся анимированный GIF величиной в 50% от исходного размера часов.

Listing 7. Capturing images one second apart
[ian@attic4 ~]$ cat getclock.sh
#!/bin/bash
windowid=$(xwininfo -name "xclock"| grep '"xclock"' | awk '{ print $4 }')
sleep 5
for n in `seq 10 69`; do
  import -frame  -window $windowid clock$n.gif&
  sleep 1s
#  usleep 998000
done
convert -resize 50% -loop 0 -delay 100 clock?[0-9].gif clocktick.gif
[ian@attic4 ~]$ ./getclock.sh
[ian@attic4 ~]$ file clocktick.gif

clocktick.gif: GIF image data, version 89a, 87 x 96

Замеры времени такого рода всегда подвержены некоторым вариациям, поэтому команда import, выполняющая захват изображений, запускается в фоновом режиме, что позволяет основному командному процессору контролировать время. Однако и в этом случае возможно некоторое отклонение, потому что для запуска каждого командного процессора в фоновом режиме все равно требуется определенное время. В примере также реализована пятисекундная задержка в начале, чтобы позволить сценарию запуститься и дать вам время нажать на часы, чтобы перевести их на передний план. Несмотря на все предостережения, в результате одного из запусков я получил одну пропущенную секунду и лишнюю копию первой секунды, поскольку для выполнения сценария потребовалось чуть больше 60 секунд. Один из способов решения этой проблемы - использование команды usleep с указанием времени в микросекундах. Это время меньше одной секунды достаточно, чтобы учесть дополнительные издержки, как указано в закомментированной строчке сценария. Если все пойдет как планировалось, результирующее изображение будет иметь вид, похожий на Рисунок 2.

Рисунок 2. Идущие часы xclock
Идущие часы xclock

В этом примере показывается, как можно снять определенное количество снимков некоторого состояния системы с регулярными интервалами. Используя приведенные здесь методики, можно снимать моментальные копии и других ситуаций в системе. Вы можете захотеть проверить результирующий файл, чтобы убедиться, что он не превышает определенного размера, или проверить, содержит ли файл определенное сообщение, или проверить состояние системы с помощью команды, например: vmstat. Единственное, что вас ограничивает - это ваши потребности и воображение.


Сигналы и прерывания

Если вы запустите сценарий getclock.sh, приведенный в Листинге 7, самостоятельно, и закроете окно часов во время работы сценария, он будет продолжать работу, выводя сообщения об ошибке каждый раз, когда будет пытаться снять моментальную копию окна часов. Точно так же, если вы запустите сценарий runclock3.sh из Листинга 4, и нажмете Ctrl-c в окне терминала, где работает этот сценарий, он немедленно завершит свою работу, не останавливая часы. Чтобы решить эти проблемы, ваш сценарий должен контролировать или перехватывать некоторые из сигналов, обсуждавшихся в главе Завершение дочернего процесса.

Если вы запустите сценарий runclock3.sh в фоновом режиме и во время его работы выполните команду ps -f, вы увидите результат, похожий на приведенный в Листинге 8.

Listing 8. Process information for runclock3.sh
[ian@attic4 ~]$ ./runclock3.sh 20s&
[1] 10101
[ian@attic4 ~]$ My PID=10101. Clock's PID=10102
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
ian      10102 10101  0 06:37 pts/1    S      0:00 xclock
ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
ian       4598 12455  0 Jul29 pts/1    00:00:00 bash
ian      10101  4598  0 06:37 pts/1    00:00:00 /bin/bash ./runclock3.sh 20s
ian      10102 10101  0 06:37 pts/1    00:00:00 xclock
ian      10104 10101  0 06:37 pts/1    00:00:00 sleep 20s
ian      10105  4598  0 06:37 pts/1    00:00:00 ps -f
[ian@attic4 ~]$ All done

[1]+  Done                    ./runclock3.sh 20s

Обратите внимание, что в выводе ps -f содержатся три записи, относящиеся к процессу runclock3.sh (PID 10101). В частности, команда sleep работает как отдельный процесс. Одним из способов обработки преждевременного завершения работы процесса xclock или использования Ctrl-c для завершения работы сценария является перехват этих сигналов и последующее завершение команды sleep с помощью команды kill.

Существует много способов определить процесс команды sleep. В Листинге 9 показана последняя версия нашего сценария, runclock4.sh. Обратите внимание на следующие моменты:

  • Команда sleep явным образом запускается в фоновом режиме.
  • Для ожидания завершения команды sleep используется команда wait.
  • Первая команда trap вызывает запуск функции stopsleep при получении сигнала SIGCHLD, SIGINT или SIGTERM. Идентификатор PID процесса sleeper передается в качестве параметра.
  • После получения сигнала вызывается функция stopsleep. Она выводит сообщение о статусе и отправляет сигнал SIGINT команде sleep.
  • Когда команда sleep по какой-либо причине завершается, выполняется условие команды wait. После этого очищаются все прерывания и завершается команда xclock.
Listing 9. Trapping signals with runclock4.sh
[ian@attic4 ~]$ cat runclock4.sh
#!/bin/bash

stopsleep() {
  sleeppid=$1
  echo "$(date +'%T') Awaken $sleeppid!"
  kill -s SIGINT $sleeppid >/dev/null 2>&1
}

runtime=${1:-10m}
mypid=$$
# Enable immediate notification of SIGCHLD
set -bm
# Run xclock in background
xclock&
clockpid=$!
#Sleep for the specified time.
sleep $runtime&
sleeppid=$!
echo "$(date +'%T') My PID=$mypid. Clock's PID=$clockpid sleep PID=$sleeppid"
# Set a trap
trap 'stopsleep $sleeppid' CHLD INT TERM
# Wait for sleeper to awaken
wait $sleeppid
# Disable traps
trap SIGCHLD
trap SIGINT
trap SIGTERM
# Clean up child (if still running)
echo "$(date +'%T') terminating"
kill -s SIGTERM $clockpid >/dev/null 2>&1 && echo "$(date +'%T') Stopping $clockpid"
echo "$(date +'%T') All done"

В Листинге 10 показан результат трехкратного запуска runclock4.sh . В первый раз выполнение завершается естественным образом. Во второй раз преждевременно завершается xclock. В третий раз сценарий прерывается нажатием Ctrl-c.

Listing 10. Stopping runclock4.sh in different ways
[ian@attic4 ~]$ ./runclock4.sh 20s
09:09:39 My PID=11637. Clock's PID=11638 sleep PID=11639
09:09:59 Awaken 11639!
09:09:59 terminating
09:09:59 Stopping 11638
09:09:59 All done
[ian@attic4 ~]$ ./runclock4.sh 20s
09:10:08 My PID=11648. Clock's PID=11649 sleep PID=11650
09:10:12 Awaken 11650!
09:10:12 Awaken 11650!
[2]+  Interrupt               sleep $runtime
09:10:12 terminating
09:10:12 All done
[ian@attic4 ~]$ ./runclock4.sh 20s
09:10:19 My PID=11659. Clock's PID=11660 sleep PID=11661
09:10:22 Awaken 11661!
09:10:22 Awaken 11661!
09:10:22 Awaken 11661!
[2]+  Interrupt               sleep $runtime
09:10:22 terminating
09:10:22 Stopping 11660
./runclock4.sh: line 31: 11660 Terminated              xclock
09:10:22 All done

Обратите внимание, сколько раз вызывалась функция stopsleep с сообщениями "Awaken". Если вы не уверены в том, почему так происходит, попробуйте сделать отдельные копии этой функции для каждого типа перехватываемых прерываний и посмотрите, что приводит к дополнительным вызовам.

Вы также отметите, что некоторые сообщения, управляющие заданиями, говорят о завершении команды xclock и прерывании команды sleep. Когда вы запускаете задание в фоновом режиме с настройками терминала bash по умолчанию, bash обычно перехватывает сигналы SIGCHLD и выводит сообщение после следующей выведенной строки. Команда set -bm в сценарии указывает bash, что нужно немедленно сообщать о сигналах SIGCHLD и разрешить мониторинг выполнения заданий. В примере с будильником, приведенном в следующем разделе, будет показано, как подавить эти сообщения.


Будильник

Наше последнее упражнение возвращает нас к исходной проблеме, которая подтолкнула к написанию этой статьи: как записывать телевизионные и радиопрограммы. Фактически мы создадим будильник. Если законодательство вашей страны позволяет записывать такие материалы для последующего использования, вы можете вместе будильника создать магнитофон, добавив программу типа vsound.

Чтобы дополнительно проиллюстрировать некоторые аспекты этого упражнения, мы будем использовать приложение GNOME rhythmbox. Даже если вы планируете использовать другой проигрыватель, это обсуждение все равно будет полезным.

Будильник может издавать любой звук, какой вы пожелаете – например, проигрывать ваши компакт-диски или файлы MP3. В центральной части Северной Каролины есть радиостанция WCPE, круглые сутки передающая классическую музыку. Кроме радиовещания, WCPE также передает потоковый звук через Интернет в нескольких форматах, в том числе в Ogg Vorbis. Если вы предпочитаете что-либо иное, укажите собственный источник звукового потока.

Чтобы запустить rhythmbox из окна терминала X Windows для проигрывания потока Ogg Vorbis станции WCPE, нужно выполнить команду, показанную в Листинге 11.

Listing 11. Starting rhythmbox with the WCPE Ogg Vorbis stream
rhythmbox --play http://audio-ogg.ibiblio.org:8000/wcpe.ogg

Первый интересный момент, касающийся rhythmbox - работающая программа может реагировать на команды, в том числе на команду остановки. Поэтому вам не нужно использовать команду kill для ее завершения, хотя, если хотите, вы можете это сделать.

Второй момент состоит в том, что большинству медиа-проигрывателей, как и часам, которые мы использовали в предыдущем примере, необходим графический вывод. Обычно, когда вы не можете находиться рядом с компьютером, вы запускаете команды средствами cron или at, что обычно предполагает, что у запланированных заданий нет доступа к дисплею. Команда rhythmbox позволяет вам указать дисплей, который необходимо использовать. Вероятно, вам нужно будет войти в систему, даже если экран заблокирован, но вы можете рассмотреть различные варианты самостоятельно. В Листинге 12 показан сценарий alarmclock.sh, который вы можете использовать в качестве основы для будильника. На вход этого сценария подается один параметр, определяющий длительность работы, которая по умолчанию составляет один час.

Listing 12. The alarm clock - alarmclock.sh
[ian@attic4 ~]$ cat alarmclock.sh
#!/bin/bash

cleanup () {
  mypid=$1
  echo "$(date +'%T') Finding child pids"
  ps -eo ppid=,pid=,cmd= --no-heading | grep "^ *$mypid"
  ps $playerpid >/dev/null 2>&1 && {
    echo "$(date +'%T') Killing rhythmbox";
    rhythmbox --display :0.0 -quit;
    echo "$(date +'%T') Killing rhythmbox done";
  }
}

stopsleep() {
  sleeppid=$1
  echo "$(date +'%T') stopping $sleeppid"
  set +bm
  kill $sleeppid >/dev/null 2>&1
}

runtime=${1:-1h}
mypid=$$
set -bm
rhythmbox --display :0.0 --play http://audio-ogg.ibiblio.org:8000/wcpe.ogg&
playerpid=$!
sleep $runtime& >/dev/null 2>&1
sleeppid=$!
echo "$(date +'%T') mypid=$mypid player pid=$playerpid sleeppid=$sleeppid"
trap 'stopsleep $sleeppid' CHLD INT TERM
wait $sleeppid
echo "$(date +'%T') terminating"
trap SIGCHLD
trap SIGINT
trap SIGTERM
cleanup $mypid final
wait

Обратите внимание на использование set +bm в функции stopsleep для изменения параметров управления заданиями и подавления сообщений, которые вы видели ранее в runclock4.sh

В Листинге 13 показан пример crontab, который будет запускать будильник с 6 до 7 утра каждый рабочий день, с 7 утра на два часа каждую субботу и с 8:30 утра на полтора часа каждое воскресенье.

Listing 13. Sample crontab to run your alarm clock
0 6 * * 1-6 /home/ian/alarmclock.sh 1h
0 7 * * 7 /home/ian/alarmclock.sh 2h
30 8 * * 0 /home/ian/alarmclock.sh 90m

Узнать, как создать запись crontab для собственного будильника, можно из предыдущего совета: Планирование заданий с помощью cron и at .

В более сложных задачах у вас может быть несколько дочерних процессов. В процедуре очистки показывается, как использовать команду ps для поиска дочерних процессов вашего сценария. Вы можете развить эту идею и организовать цикл по произвольному множеству дочерних процессов и завершить их все.


Дополнительная информация

Если вы хотите узнать больше об администрировании Linux, прочтите руководство "Подготовка к экзамену LPI 102: Административные задачи (EN)" или ознакомьтесь с другими Ресурсами, перечисленными ниже. Не забудьте проголосовать за эту страницу и сообщить нам, какие еще советы вы желаете увидеть.

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, AIX и UNIX, Open source
ArticleID=259421
ArticleTitle=Советы по Linux: Управление длительностью выполнения запланированных заданий
publish-date=10022007