Работа со временем в bash.

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Работа со временем в bash.

Сообщение Yaros »

Возникла потребность создать скрипт, в котором определенное действие будет происходить через 3 минуты после того, как выполнится другое.
Так же нужно узнать выполнилось ли то действие (есть команда, возвращающая false в случае выполнения, и true - если еще не выполнено). Для этого подумывал сделать цикл, раз в неск. секунд делающий запрос. Интересно можно ли сделать такой цикл и не сильно ли он загрузит систему.
Хотелось бы услышать совет, как сделать подобное или хотя бы пинок в сторону нормального мана на русском (именно по времени).
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Работа со временем в bash.

Сообщение Yaros »

Yaros писал(а):
03.11.2009 17:46
Возникла потребность создать скрипт, в котором определенное действие будет происходить через 3 минуты после того, как выполнится другое.

Разобрался с этой частью вопроса: screen подходит идеально... Остался цикл.
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Работа со временем в bash.

Сообщение SLEDopit »

Yaros писал(а):
03.11.2009 17:46
Возникла потребность создать скрипт, в котором определенное действие будет происходить через 3 минуты после того, как выполнится другое.
я чего-то не понимаю или

Код: Выделить всё

command1 && sleep 3m && command2
нынче не в моде?
или там еще что-то должно происходить параллельно?
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
vr13
Сообщения: 885
ОС: gentoo

Re: Работа со временем в bash.

Сообщение vr13 »

чтобы не циклить и не грузить систему, нужно спать (sleep) и "действия" - выполнять асинхронно и дожидаться завершения - см wait, waitpid. асинхронность еще можно реализовать через внешнюю команду - at. вариантов, как обычно в *nix - не один, кроме названных скорее всего можно еще чего-нить придумать. screen к этому наверное тоже можно приспособить, но я не могу придумать как )
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Работа со временем в bash.

Сообщение SLEDopit »

vr13 писал(а):
03.11.2009 19:04
screen к этому наверное тоже можно приспособить, но я не могу придумать как )

Код: Выделить всё

screen -S temp sleep 3m
=)
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Работа со временем в bash.

Сообщение Yaros »

SLEDopit писал(а):
03.11.2009 18:57
Yaros писал(а):
03.11.2009 17:46
Возникла потребность создать скрипт, в котором определенное действие будет происходить через 3 минуты после того, как выполнится другое.
я чего-то не понимаю или

Код: Выделить всё

command1 && sleep 3m && command2
нынче не в моде?
или там еще что-то должно происходить параллельно?

Я в предыдущем комменте уже написал:
Разобрался с этой частью вопроса: screen подходит идеально.

Я просто со sleep'ом не был знаком :(
Блин, очепятался! Конечно же sleep!
Кстати, попутно решил вторую часть вопроса: можно сделать цикл, и, если результат равен true, делаем "sleep 3s" и повторяем цикл. Если же false, делаем "command1 && sleep 3m && command2".
Интересно только, не сильно ли подобные скрипты будут тормозит работу при запущеных "тяжелых" приложениях.
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Работа со временем в bash.

Сообщение SLEDopit »

Yaros писал(а):
03.11.2009 19:20
Кстати, попутно решил вторую часть вопроса: можно сделать цикл, и, если результат равен true, делаем "sleep 3s" и повторяем цикл. Если же false, делаем "command1 && sleep 3m && command2".
зачем цикл?
в конструкции

Код: Выделить всё

command1 && sleep 3m && command2
&& уже проверяет успешность завершения предыдущей команды после ее завершения.
если все хорошо - управление передается следующей команде, если нет, то все завершается.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Работа со временем в bash.

Сообщение Yaros »

SLEDopit писал(а):
03.11.2009 19:34
Yaros писал(а):
03.11.2009 19:20
Кстати, попутно решил вторую часть вопроса: можно сделать цикл, и, если результат равен true, делаем "sleep 3s" и повторяем цикл. Если же false, делаем "command1 && sleep 3m && command2".
зачем цикл?
в конструкции

Код: Выделить всё

command1 && sleep 3m && command2
&& уже проверяет успешность завершения предыдущей команды после ее завершения.
если все хорошо - управление передается следующей команде, если нет, то все завершается.

Вы неправильно поняли.Чтобы выполнить "command1 && sleep 3m && command2", нужно в цикле получить определенное значение. Цикл должен выполняться каждые n секунд до получения значения false. После получения этого значения выполняется "command1 && sleep 3m && command2",
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Работа со временем в bash.

Сообщение SLEDopit »

а, ну тогда это будет выглядеть вот так:

Код: Выделить всё

i=0;while [ $i -eq 0 ]; do command || i=1; done
command1 && sleep 3m && command2
зачем второй цикл то?
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Работа со временем в bash.

Сообщение Yaros »

SLEDopit писал(а):
03.11.2009 20:22
а, ну тогда это будет выглядеть вот так:

Код: Выделить всё

i=0;while [ $i -eq 0 ]; do command || i=1; done
command1 && sleep 3m && command2
зачем второй цикл то?

Там один цикл :) Видимо я криво изъясняюсь... Я просто размышлял, как сделать, чтобы цикл выполнялся раз в определенное количество секунд.
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Работа со временем в bash.

Сообщение SLEDopit »

Yaros писал(а):
03.11.2009 20:55
Видимо я криво изъясняюсь...
может еще мой затуманенный бессонными ночами разум сбоит =)
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Работа со временем в bash.

Сообщение t.t »

SLEDopit писал(а):
03.11.2009 20:22
а, ну тогда это будет выглядеть вот так:

Код: Выделить всё

i=0;while [ $i -eq 0 ]; do command || i=1; done
command1 && sleep 3m && command2
зачем второй цикл то?
А зачем переменная?

Код: Выделить всё

while command; do :; done


Yaros писал(а):
03.11.2009 20:55
Я просто размышлял, как сделать, чтобы цикл выполнялся раз в определенное количество секунд.
Тогда немного не так, но тоже всё просто:

Код: Выделить всё

while command; do sleep 3; done


t.t писал(а):
04.11.2009 14:59
SLEDopit писал(а):
03.11.2009 20:22
а, ну тогда это будет выглядеть вот так:

Код: Выделить всё

i=0;while [ $i -eq 0 ]; do command || i=1; done
command1 && sleep 3m && command2
зачем второй цикл то?
А зачем переменная?

Код: Выделить всё

while command; do :; done
Подозреваю, что у Вас подействовал распространённый шаблон: воспринимать while [ ... ] как одну конструкцию. На самом же деле условием в цикле while выступает любая команда (точнее, код её завершения). И [ -- это тоже команда:

Код: Выделить всё

t:~$ which [
/usr/bin/[
; почти синоним к команде test, с той лишь разницей, что требует, чтобы последним аргументом была закрывающая скобка.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Работа со временем в bash.

Сообщение Yaros »

t.t писал(а):
04.11.2009 14:59
Yaros писал(а):
03.11.2009 20:55
Я просто размышлял, как сделать, чтобы цикл выполнялся раз в определенное количество секунд.
Тогда немного не так, но тоже всё просто:

Код: Выделить всё

while command; do sleep 3; done


Код:

function check_playing { $(dcop amarok player isPlaying) } while [[ $(check_playing) = true ]]; do sleep 10 done echo Rule!

Суть в том, что если функция check_playing возвращает true, нужно "уснуть" на 10 секунд, а затем проверить еще раз условие. Когда условие станет false, нужно сотворить какое-то действие (в этом примере - "echo Rule!")
t.t писал(а):
04.11.2009 14:59
SLEDopit писал(а):
03.11.2009 20:22
а, ну тогда это будет выглядеть вот так:

Код: Выделить всё

i=0;while [ $i -eq 0 ]; do command || i=1; done
command1 && sleep 3m && command2
зачем второй цикл то?
А зачем переменная?

Код: Выделить всё

while command; do :; done


Ойк... не вкурил. Оно выполняется, пока команда возвращает ненулевое значение?
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
BIgAndy
Сообщения: 1923

Re: Работа со временем в bash.

Сообщение BIgAndy »

Yaros писал(а):
03.11.2009 17:46
Возникла потребность создать скрипт, в котором определенное действие будет происходить через 3 минуты после того, как выполнится другое.
....подумывал сделать цикл, раз в неск. секунд делающий запрос.

man cron
и man bash на предмет амперсандов & и &&
Так же нужно узнать выполнилось ли то действие

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

Можно, но зачем костыли, когда есть штаное проверенное десятилетиями решение.?
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Работа со временем в bash.

Сообщение t.t »

Yaros писал(а):
05.11.2009 17:33
t.t писал(а):
04.11.2009 14:59
Yaros писал(а):
03.11.2009 20:55
Я просто размышлял, как сделать, чтобы цикл выполнялся раз в определенное количество секунд.
Тогда немного не так, но тоже всё просто:

Код: Выделить всё

while command; do sleep 3; done


Код:

function check_playing { $(dcop amarok player isPlaying) } while [[ $(check_playing) = true ]]; do sleep 10 done echo Rule!

Суть в том, что если функция check_playing возвращает true, нужно "уснуть" на 10 секунд, а затем проверить еще раз условие. Когда условие станет false, нужно сотворить какое-то действие (в этом примере - "echo Rule!")
Функции в bash (как и команды) не возвращают true, они возвращают числовые значения, коды ошибок. Код успешного завершения -- 0. Цикл, написанный мною выше, именно это и делает: пока команда выполняется успешно, ждёт по 3 секунды и проверяет заново; а как только команда завершится с ошибкой, управление пойдёт дальше.

Yaros писал(а):
05.11.2009 17:33
t.t писал(а):
04.11.2009 14:59
SLEDopit писал(а):
03.11.2009 20:22
а, ну тогда это будет выглядеть вот так:

Код: Выделить всё

i=0;while [ $i -eq 0 ]; do command || i=1; done
command1 && sleep 3m && command2
зачем второй цикл то?
А зачем переменная?

Код: Выделить всё

while command; do :; done
Ойк... не вкурил. Оно выполняется, пока команда возвращает ненулевое значение?
Пока возвращает нулевое, т.е. пока выполняется успешно. В shell возвращаемые значения в этом смысле "наоборот" по сравнению с процедурными языками, но на практике так удобнее: кодов ошибок может быть несколько, а успешное завершение -- оно всегда одинаковое.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Работа со временем в bash.

Сообщение t.t »

BIgAndy писал(а):
05.11.2009 20:12
Yaros писал(а):
03.11.2009 17:46
Возникла потребность создать скрипт, в котором определенное действие будет происходить через 3 минуты после того, как выполнится другое.
....подумывал сделать цикл, раз в неск. секунд делающий запрос.
man cron
и man bash на предмет амперсандов & и &&
Так же нужно узнать выполнилось ли то действие
Парсим логи или выставляем флаги. зависит от собственной одаренности.

Интересно можно ли сделать такой цикл и не сильно ли он загрузит систему.
Хотелось бы услышать совет, как сделать подобное или хотя бы пинок в сторону нормального мана на русском (именно по времени).
Можно, но зачем костыли, когда есть штаное проверенное десятилетиями решение.?
Штатные, провереные десятилетиями решения хорошо использовать к месту. Как Вы предлагаете применять крон для запуска не _в_ конкретное время, а _через_ столько-то минут после выполнения другой команды? Тут at ещё как-то можно прикрутить, но и то со sleep проще. А уж cron-то тут при чём?

А предложение парсить логи (которых может и не быть) или выставлять какие-то флаги для проверки успешности завершения некой команды -- это как раз игнорирование "штатных, проверенных десятилетиями решений": ||, &&, if, while.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Работа со временем в bash.

Сообщение Yaros »

t.t писал(а):
06.11.2009 11:25
Функции в bash (как и команды) не возвращают true, они возвращают числовые значения, коды ошибок. Код успешного завершения -- 0. Цикл, написанный мною выше, именно это и делает: пока команда выполняется успешно, ждёт по 3 секунды и проверяет заново; а как только команда завершится с ошибкой, управление пойдёт дальше.

А как тогда проверить на true/false? Писать в переменную результат $(dcop amarok player isPlaying), а затем сравнивать как строку?
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Работа со временем в bash.

Сообщение drBatty »

Yaros писал(а):
06.11.2009 18:17
А как тогда проверить на true/false?

так и проверять:

Код: Выделить всё

if command; then
 echo "TRUE!"
else
 echo "FALSE"
fi


Кроме того, можно проанализировать код ошибки, он в $?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
BIgAndy
Сообщения: 1923

Re: Работа со временем в bash.

Сообщение BIgAndy »

t.t писал(а):
06.11.2009 11:32
Штатные, провереные десятилетиями решения хорошо использовать к месту. Как Вы предлагаете применять крон для запуска не _в_ конкретное время, а _через_ столько-то минут после выполнения другой команды? Тут at ещё как-то можно прикрутить, но и то со sleep проще. А уж cron-то тут при чём?


Я же написал "man cron"
In other case cron checks each minute to see if its crontables modtime have changes and reload those which have changes.

А предложение парсить логи (которых может и не быть) или выставлять какие-то флаги для проверки успешности завершения некой команды -- это как раз игнорирование "штатных, проверенных десятилетиями решений": ||, &&, if, while.

Совершенно верно. АКА костыль.
Но если нужен более глубоккий анализ условий завершения, без анализа stdout не обойтись.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Работа со временем в bash.

Сообщение t.t »

BIgAndy писал(а):
07.11.2009 11:29
t.t писал(а):
06.11.2009 11:32
Штатные, провереные десятилетиями решения хорошо использовать к месту. Как Вы предлагаете применять крон для запуска не _в_ конкретное время, а _через_ столько-то минут после выполнения другой команды? Тут at ещё как-то можно прикрутить, но и то со sleep проще. А уж cron-то тут при чём?
Я же написал "man cron"
In other case cron checks each minute to see if its crontables modtime have changes and reload those which have changes.
И что? Я знаю, что и через крон это _можно_ сделать (вообще, unix тем и хорош, что любую задачу позволяет сделать большим количеством разных методов). Вопрос в том, _нужно_ ли? Решение с помощью крона в данном случае будет сложнее, чем использование sleep, а какие плюсы от него _в данном случае_?

BIgAndy писал(а):
07.11.2009 11:29
А предложение парсить логи (которых может и не быть) или выставлять какие-то флаги для проверки успешности завершения некой команды -- это как раз игнорирование "штатных, проверенных десятилетиями решений": ||, &&, if, while.
Совершенно верно. АКА костыль.
Но если нужен более глубоккий анализ условий завершения, без анализа stdout не обойтись.
Если нужен -- тогда конечно. Но автор темы никак не дал понять, что он ему нужен.

Одним словом, мне кажется, что Вы изобретаете сложности на ровном месте.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
BIgAndy
Сообщения: 1923

Re: Работа со временем в bash.

Сообщение BIgAndy »

t.t писал(а):
07.11.2009 12:04
а какие плюсы от него _в данном случае_?

Авторестарт при креше . При наличии anacron возможна автоматичесоее выполнение пропущенных заданий..
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Работа со временем в bash.

Сообщение drBatty »

BIgAndy писал(а):
05.11.2009 20:12
Возникла потребность создать скрипт, в котором определенное действие будет происходить через 3 минуты после того, как выполнится другое.
....подумывал сделать цикл, раз в неск. секунд делающий запрос.


man cron

t.t писал(а):
07.11.2009 12:04
И что? Я знаю, что и через крон это _можно_ сделать (вообще, unix тем и хорош, что любую задачу позволяет сделать большим количеством разных методов). Вопрос в том, _нужно_ ли

иногда - нужно. например, если действия выполняются одним и тем-же скриптом - его можно тогда вызывать по crond каждые 3 минуты, а уж сам скрипт будет решать что нужно делать. Существенный плюс: этот скрипт не будет постоянно висеть в памяти. Хотя конечно случай редкий (однако я на практике примерно так делал).

t.t писал(а):
07.11.2009 12:04
Если нужен -- тогда конечно. Но автор темы никак не дал понять, что он ему нужен.

Одним словом, мне кажется, что Вы изобретаете сложности на ровном месте.

для анализа stdout прелестно подходит sed:
sed 's/.*/command/ep;<а тут мы анализируем вывод>'
Впрочем нужно это редко. Преимущества перед решением на bash:
1) в bash плохо реализованы регулярные выражения.
2) sed быстрее.

t.t, это только замечания, в целом вы безусловно правы.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Работа со временем в bash.

Сообщение t.t »

В качестве замечаний -- полностью согласен. Я лишь пытаюсь предостеречь, в том числе и автора темы, от достаточно распространённой ошибки: избирать самый надёжный или самый функциональный путь даже когда он явно избыточен, и достаточно будет простого и незатейливого. Тем самым стремясь к экономии времени автоматизацией задач, можно получить лишние затраты на саму автоматизацию.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали: