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

Re: shell background job and trap SIGCHILD



27.10.2016 23:56, Artem Chuprina пишет:
> Михаил Касаджиков -> 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'ом) и посмотреть, будет ли разница.

У ksh93, dash и bash — buildin. И man {k,da,ba}sh со мной согласен.

>  > Ksh реагирует на дочерние процессы «(…) &». Пользовательские функции и внешние программы он игнорирует.
>
>  > Документация, к сожалению, явно не указывает как именно это дело должно обрабатываться.
>
> Я не исключу, что это вопрос не к "как обрабатывается", а к "как
> запускается". Хотя, конечно, интеллект на тему "в реальном обработчике
> SIGCHLD отфильтровать завершившиеся PID'ы по списку именно бэкграундных
> задач" в продвинутых шеллах вполне возможен.

В процессах видны дочерние {k,da,ba}sh и sleep.


Проверил по другому, таки да, на function() dash не реагирует, CHLD срабатывал именно на date.

Так что, ksh реагирует на «(…) &», а dash ещё и на внешние программы. Bash — пофигист.



Reply to: