[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: shell background job and trap SIGCHILD



Михаил Касаджиков -> Andrey Nikitin  @ Thu, 27 Oct 2016 22:59:51 +0300:

 >>> Есть подозрение что dash и bash имеют баг в обработке команды trap arg SIGCHLD.
 >>>
 >>> Есть некий шелл скрипт (код в конце письма), который (imho) должен работать так,
 >>> как он работает только в ZSH.
 >>> А именно, обработчик SIGCHLD должен быть вызван _сразу_ после завершения фонового процесса.
 >>>
 >>> % zsh ./bg.sh 
 >>> 13:02:08: parent 32128, child 32131
 >>> 13:02:10: child exited after 2 sec
 >>> 13:02:10: SIGCHLD 32131
 >>> 13:02:12: bye...
 >>>
 >>> Bash-у вообще на..ть на установленный обработчик SIGCHLD
 >>> % bash ./bg.sh  
 >>> 13:03:06: parent 32149, child 32150
 >>> 13:03:08: child exited after 2 sec
 >>> 13:03:10: bye...
 >>>
 >>> Ну а "родной" /bin/sh он же Dash лучше бы и не делал ничего.
 >>> % dash ./bg.sh
 >>> 13:03:49: parent 32157, child 32158
 >>> 13:03:49: SIGCHLD 32158
 >>> 13:03:51: child exited after 2 sec
 >>> 13:03:53: SIGCHLD 32158
 >>> 13:03:53: bye...
 >>> 13:03:53: SIGCHLD 32158
 >>>
 >>> WTF?
 >>>
 >>> [code]
 >>> print_msg()
 >>> {
 >>>    echo "`date +%H:%M:%S`: $@"
 >>> }
 >>>
 >>> on_sigchld() {
 >>>    trap '' CHLD
 >>>    print_msg "SIGCHLD $!"
 >>>    trap on_sigchld CHLD
 >>> }
 >>>
 >>> trap on_sigchld CHLD
 >>>
 >>> (
 >>>    sleep 2
 >>>    print_msg "child exited after 2 sec"
 >>> ) &
 >>>
 >>> print_msg "parent $$, child $!"
 >>>
 >>> sleep 4
 >>> print_msg "bye..."
 >>> [/code]
 >>>
 >> Dash отрабатывает правильно — у него нет встроенной реализации sleep и для
 >> этого он вызывает внешнюю программу — её SIGCHILD мы и ловим.
 >>
 >> Ksh тоже работает как и ожидается.
 >>
 >> А вот bash это дело игнорирует.
 >>
 >>
 > Всё ещё веселее.

 > Dash реагирует как на вызов внешних программ, так и на вызовы пользовательских
 > функций «print_msg()». И это не считая дочерние процессы «(…) &».

В print_msg вызывается echo. Кто сказал, что оно сегодня builtin? У
классического sh - нет, внешняя программа. Можно заменить на print (этот
обязан быть builtin'ом) и посмотреть, будет ли разница.

 > Ksh реагирует на дочерние процессы «(…) &». Пользовательские функции и внешние программы он игнорирует.

 > Документация, к сожалению, явно не указывает как именно это дело должно обрабатываться.

Я не исключу, что это вопрос не к "как обрабатывается", а к "как
запускается". Хотя, конечно, интеллект на тему "в реальном обработчике
SIGCHLD отфильтровать завершившиеся PID'ы по списку именно бэкграундных
задач" в продвинутых шеллах вполне возможен.


Reply to: