Есть бесконечный цикл типа while true;do ....;done
Хочу сделать так чтобы он заканчивал цикл при нажатии Ctrl+c, для асинхронного выполнения можно использовать &, пример:
sleep 5 & ls -l ... Но вот там то куда его воткнуть? Там идет цикл потом тело цикла ... без понятия куда его там можно вставить.
Асинхронное выполнение команд
TerMih, опишите, пожалуйста, подробнее стоящую перед вами задачу.
Если вам нужно следить за изменениями в определённой директории, попробуйте
[console]watch -d -n 5 ls -l[/console]
И вдогонку, возможно, заинтересует:
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
while true; do mplayer -vo xv "${result[ ` expr $number_film - 1 ` ]}"; done
Вот и проблема :) Он циклит на всегда :) Ctrl + C уже не помагает :)
Вот и хотел узнать, как сделать так чтобы все таки он завершал цикл при нажатии именно Ctrl+C
Решил проблему с помощью добавления в тело цикла sleep 0.3 НО в этом случае надо нажать 2 раза Ctrl+C, а хочу чтобы 1 раз надо было нажать, как ?
while mplayer -vo xv "${result[ ` expr $number_film - 1 ` ]}"; do; done
не?
все проще: надо в (скобки) завернуть команды, которые будут выполнятся отдельгым процессом в субшелле. При должной аккуратности такое работает даже в продакшене.
и да, в 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]
А в вике есть:
Классификация сигналов
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
В чём проблема?
Решил проблему с помощью добавления в тело цикла sleep 0.3 НО в этом случае надо нажать 2 раза Ctrl+C, а хочу чтобы 1 раз надо было нажать, как ?
очень просто: если команда завершилась по прерыванию, например SIGINT (CTRL+C), то код возврата равен 128+номер сигнала.
т.к. обычно SIGINT == 2, то код завершения равен 130
if [ $? == 130 ]; then
echo прошлая программа была прервана
exit 130
fiМожет как-то так:
(a=false; while [ $a == false ]; do mplayer -vo xv "${result[ ` expr $number_film - 1 ` ]}"; done) & (read -rsn1; a=true)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
( if [$? -eq 1] ;then exit 1; fi)
пробелы после и перед скобками не забыли?
Fat-Zer, проверьте у себя на машине пожалуйста, я уже везде там понаставил пробелы и не работает ... Может проблема не в пробелах? А я что то в корне не верно делаю? Да и вроде как если бы пробел не поставил, то он мне выдал бы извещение о ошибке,а ее нет...
while true ; do (mplayer -vo xv "03446"*) && (exit 1); done
while true ; do (mplayer -vo xv "03446"*) || (exit 1); done
НЕ РАБОТАЕТ!!! да как так!
ПОЧЕМУ!!!!! 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"*
В чем разница то????
Пишу (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]
ПОЧЕМУ!!!!! while true ; do (mplayer -vo xv "03446"*) || (exit 1); done ТАК НЕ РАБОТАЕТ!!!
а вот так while true ; do mplayer -vo xv "03446"* || exit 1; done. РАБОТАЕТ! Чем ему скобки не угодили? Форма записи
скобки - это не форма записи man bash срочно и читать про составные команды.
В вашей ссылке не понятно почему все таки 128+...
по POSIX-стандарту. Доказывать лень, объяснять нет смысла.
Но я написал такую вещь 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
ну ещё-бы...
(while true; do mplayer -vo xv "03446"*; done) &
это отдельный шелл. на него ctrl+c действует, mplayer прерывается, и опять по новой.
while true ; do (mplayer -vo xv "03446"*) || (exit 1); done
В чем разница то????
скобки - это оттдельный суб-процесс.
Т.е. запись:
( command )
приводит к тому, что запускается дочерний процесс, а уж в нём - команда.
смотрите сами:
$ ( sleep 1h ) &
[1] 11656
$ pstree
init-+-acpid
|-bash---startx---xinit-+-X
| `-ck-launch-sessi-+-gnome-session-+-Terminal-+-bash-+-pstree
| | | | `-sleep
видите?
команда sleep 1h запущена из терминала и работает, одновременно работает команда pstree из того-же терминала.
ПОЧЕМУ!!!!! 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.
Какой шаг вам непонятен?
вам надо, чтобы mplayer играл, пока не упадёт(от сигнала или ещё по какой причине)?
Да, методом научного тыка я уже добился этого
while true ; do mplayer -vo xv "03446"* || exit 1; done. РАБОТАЕТ!
Спасибо всем за терпение, помощь. :)
drBatty, Спасибо огромное, не думал, что тут так все запутано :)