LinuxForum.Fans
Тема

Асинхронное выполнение команд

Автор: TerMih 22 сообщений 3621 просмотров
#180748

Есть бесконечный цикл типа while true;do ....;done
Хочу сделать так чтобы он заканчивал цикл при нажатии Ctrl+c, для асинхронного выполнения можно использовать &, пример:
sleep 5 & ls -l ... Но вот там то куда его воткнуть? Там идет цикл потом тело цикла ... без понятия куда его там можно вставить.

#180751

TerMih, опишите, пожалуйста, подробнее стоящую перед вами задачу.
Если вам нужно следить за изменениями в определённой директории, попробуйте
[console]watch -d -n 5 ls -l[/console]

#180754

И вдогонку, возможно, заинтересует:
dnotify — Execute a command when the contents of a directory change
inotify-tools — A set of command-line programs providing a simple interface to inotify
incron — Inotify based cron daemon

#180769

while true; do mplayer -vo xv "${result[ ` expr $number_film - 1 ` ]}"; done
Вот и проблема :) Он циклит на всегда :) Ctrl + C уже не помагает :)
Вот и хотел узнать, как сделать так чтобы все таки он завершал цикл при нажатии именно Ctrl+C

#180772

Решил проблему с помощью добавления в тело цикла sleep 0.3 НО в этом случае надо нажать 2 раза Ctrl+C, а хочу чтобы 1 раз надо было нажать, как ?

#180821

while mplayer -vo xv "${result[ ` expr $number_film - 1 ` ]}"; do; done
не?

#180837

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

#180885

и да, в bash'е есть
[console]$ help trap
trap: trap [-lp] [[arg] signal_spec ...]
Trap signals and other events.

Defines and activates handlers to be run when the shell receives signals
or other conditions.

ARG is a command to be read and executed when the shell receives the
signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC
is supplied) or `-', each specified signal is reset to its original
value. If ARG is the null string each SIGNAL_SPEC is ignored by the
shell and by the commands it invokes.

If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If
a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.

If no arguments are supplied, trap prints the list of commands associated
with each signal.

Options:
-l print a list of signal names and their corresponding numbers
-p display the trap commands associated with each SIGNAL_SPEC

Each SIGNAL_SPEC is either a signal name in <signal.h> or a signal number.
Signal names are case insensitive and the SIG prefix is optional. A
signal may be sent to the shell with "kill -signal $$".

Exit Status:
Returns success unless a SIGSPEC is invalid or an invalid option is given.
[/console]
А в вике есть:
Классификация сигналов

text
POSIX определяет 28 сигналов, которые можно классифицировать следующим образом:
Название     Действие по умолчанию     Описание     Тип
...
SIGINT     Завершение     Сигнал прерывания (Ctrl-C) с терминала     Управление

http://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%B3%D0%BD%D0%B0%D0%BB%D1%8B_%28UNIX%29

В чём проблема?

#180889
TerMih написал:
Решил проблему с помощью добавления в тело цикла sleep 0.3 НО в этом случае надо нажать 2 раза Ctrl+C, а хочу чтобы 1 раз надо было нажать, как ?

очень просто: если команда завершилась по прерыванию, например SIGINT (CTRL+C), то код возврата равен 128+номер сигнала.
т.к. обычно SIGINT == 2, то код завершения равен 130

text
if [ $? == 130 ]; then
  echo прошлая программа была прервана
  exit 130
fi
#181224

Может как-то так:

text
(a=false; while [ $a == false ]; do mplayer -vo xv "${result[ ` expr $number_film - 1 ` ]}"; done) & (read -rsn1; a=true)
#181519

while mplayer -vo xv "${result[ ` expr $number_film - 1 ` ]}"; do; done
не?

Классно, только одна не точность, пустой do не может быть ... Но это пустяк.

очень просто: если команда завершилась по прерыванию, например SIGINT (CTRL+C), то код возврата равен 128+номер сигнала.
т.к. обычно SIGINT == 2, то код завершения равен 130

if [ $? == 130 ]; then
echo прошлая программа была прервана
exit 130
fi

В вашей ссылке не понятно почему все таки 128+...
Но я написал такую вещь mplayer -vo xv "..."; echo $?
При нажатии Ctrl+C он мне вывел "1"
Пишу (while true; do mplayer -vo xv "03446"*; done) & ( if [$? -eq 1] ;then exit 1; fi)
И он 0 Эмоций! Даже если нажимаешь Ctrl+C вообще не обращает на это внимание ...
Перебирал методом тыка и 129 и 130 и 2 и 1... реакции 0

#181526
TerMih написал:
( if [$? -eq 1] ;then exit 1; fi)

пробелы после и перед скобками не забыли?

#181530

Fat-Zer, проверьте у себя на машине пожалуйста, я уже везде там понаставил пробелы и не работает ... Может проблема не в пробелах? А я что то в корне не верно делаю? Да и вроде как если бы пробел не поставил, то он мне выдал бы извещение о ошибке,а ее нет...

#181534

while true ; do (mplayer -vo xv "03446"*) && (exit 1); done
while true ; do (mplayer -vo xv "03446"*) || (exit 1); done
НЕ РАБОТАЕТ!!! да как так!

#181537

ПОЧЕМУ!!!!! while true ; do (mplayer -vo xv "03446"*) || (exit 1); done ТАК НЕ РАБОТАЕТ!!!
а вот так while true ; do mplayer -vo xv "03446"* || exit 1; done. РАБОТАЕТ! Чем ему скобки не угодили? Форма записи

команда1 || команда2,
то команда2 выполняется при ненулевом коде завершения команды1. Например,
команда

Чем ему так не понравились скобки? Я явно отделил команду №1 от команды №2, а он не хочет так работать?
Я уже если честно вообще запутался в этих скобках ... где их ставить,а где нет, где писать echo "123*", а где писать echo "123"*
В чем разница то????

#181539
TerMih написал:
Пишу (while true; do mplayer -vo xv "03446"*; done) & ( if [$? -eq 1] ;then exit 1; fi)

что это вообще за бред... он до if'а не дойдёт...
пишите, что вам нужно сделать... а то не понятно уже.
вам надо, чтобы mplayer играл, пока не упадёт(от сигнала или ещё по какой причине)?
тогда самый топорный вариант:
[console](while true; do mplayer -vo xv <файлы> || exit $?; done)[/console]

#181543
TerMih написал:
ПОЧЕМУ!!!!! while true ; do (mplayer -vo xv "03446"*) || (exit 1); done ТАК НЕ РАБОТАЕТ!!!
а вот так while true ; do mplayer -vo xv "03446"* || exit 1; done. РАБОТАЕТ! Чем ему скобки не угодили? Форма записи

скобки - это не форма записи man bash срочно и читать про составные команды.

#181545
TerMih написал:
В вашей ссылке не понятно почему все таки 128+...

по POSIX-стандарту. Доказывать лень, объяснять нет смысла.

TerMih написал:
Но я написал такую вещь mplayer -vo xv "..."; echo $?
При нажатии Ctrl+C он мне вывел "1"

ну значит там какой-то нестандартный обработчик прерываний.

TerMih написал:
Пишу (while true; do mplayer -vo xv "03446"*; done) & ( if [$? -eq 1] ;then exit 1; fi)
И он 0 Эмоций! Даже если нажимаешь Ctrl+C вообще не обращает на это внимание ...
Перебирал методом тыка и 129 и 130 и 2 и 1... реакции 0

ну ещё-бы...
(while true; do mplayer -vo xv "03446"*; done) &
это отдельный шелл. на него ctrl+c действует, mplayer прерывается, и опять по новой.

TerMih написал:
while true ; do (mplayer -vo xv "03446"*) || (exit 1); done
TerMih написал:
В чем разница то????

скобки - это оттдельный суб-процесс.

Т.е. запись:

( command )

приводит к тому, что запускается дочерний процесс, а уж в нём - команда.
смотрите сами:

text
$ ( sleep 1h ) &
[1] 11656
$ pstree 
init-+-acpid
     |-bash---startx---xinit-+-X
     |                       `-ck-launch-sessi-+-gnome-session-+-Terminal-+-bash-+-pstree
     |                                         |               |          |      `-sleep

видите?
команда sleep 1h запущена из терминала и работает, одновременно работает команда pstree из того-же терминала.

TerMih написал:
ПОЧЕМУ!!!!! while true ; do (mplayer -vo xv "03446"*) || (exit 1); done ТАК НЕ РАБОТАЕТ!!!
а вот так while true ; do mplayer -vo xv "03446"* || exit 1; done. РАБОТАЕТ! Чем ему скобки не угодили?

первая конструкция работает. Вы подумайте сами, ЧТО вы сделали:
1) запустили (mplayer -vo xv "03446"*) в отдельном субшеле.
2) его прервали. Код возврата просочился за скобки
3) код возврата был проанализирован ||, и
4) выполнился отдельный субшелл ( exit )
5) этот субшелл сразу завершился с кодом один. мы опять в родительском шелле, выполняем done.

Какой шаг вам непонятен?

#181547

вам надо, чтобы mplayer играл, пока не упадёт(от сигнала или ещё по какой причине)?

Да, методом научного тыка я уже добился этого

while true ; do mplayer -vo xv "03446"* || exit 1; done. РАБОТАЕТ!

Спасибо всем за терпение, помощь. :)

#181550

drBatty, Спасибо огромное, не думал, что тут так все запутано :)

Войдите или зарегистрируйтесь, чтобы ответить.