Восстановите способность использовать ^ C для закрытия фоновых, а затем (эффективно) фоновых процессов

На Debian это должно быть просто изменением профиля Pulse Audio. Для меня это просто:

pactl set-card-profile 0 output:hdmi-stereo

Номер карты и название профиля, который вам нужен, могут отличаться. Вы можете посмотреть доступные варианты, сделав:

pactl list cards
3
22.04.2019, 13:30
2 ответа

Самое простое, что вы можете сделать, это перехватитьSIGINT(^C )и убить фоновый процесс из обработчика:

#! /bin/sh
trap 'kill "$!"; exit 1' INT QUIT
zenity --info &
wait

См. этот и другие подобные ответы для объяснения этого поведения.

При вызове вашего скрипта из некоторых оболочек, таких как bash, которые реализуют так -называемый «Ожидание и совместный выход»(см. здесь для обсуждения ), ожидаемый способ корректного выхода программы после получения сигнала — сброс обработчика и последующее уничтожение себя тем же сигналом:

#! /bin/sh
termsig(){ trap - "$1"; kill "$!"; kill -s "$1" "$$"; }
trap 'termsig INT' INT
trap 'termsig QUIT' QUIT 
zenity --info &
wait

Все это, конечно, довольно грубо и ничего не сможет сделать с дочерними процессами, которые zenityсами могли породить, и их придется адаптировать более чем для одного фонового процесса. Более очевидное решение (trap - INT; zenity --info) &не будет не работать с /bin/shиз любых дистрибутивов, производных от Debian -, (Ubuntu и т. д. )или с любыми системами на основе busybox -.

Другим решением может быть запуск вашей программы через оболочку, которая позволяет сбросить расположение SIGINTпо умолчанию, например. сperl:

#! /bin/sh
perl -e '$SIG{INT} = $SIG{QUIT} = "DEFAULT"; exec @ARGV' zenity --info &
wait

Но если вы пойдете этим путем, вы можете точно так же -переписать весь свой сценарий в perlили python;-)

2
27.01.2020, 21:17

В не-интерактивном shкомандам, выполняемым асинхронно с &, игнорируются их сигналы SIGINT и SIGQUIT.

Это требование POSIX, и оно восходит к временам, когда терминальное управление заданиями(tcsetpgrp()... )не существовало. Сегодня это вообще мешает.

Еще одно требование POSIX, происходящее из того же источника, заключается в том, что если сигнал игнорируется при запуске оболочки, его нельзя -игнорировать с помощью trap. Опять же, в наши дни это нежелательное и раздражающее поведение.

zshреализует это последнее требование лишь частично. trap - SIGNALдля восстановления расположения по умолчанию игнорируемого SIGNALигнорируется, но trap handler SIGNALустанавливает handlerдля СИГНАЛА, даже если этот СИГНАЛ был проигнорирован при запуске, поэтому можно восстановить расположение по умолчанию, если они действительно хотят к с trap : SIGNAL; trap - SIGNAL.

Пока SIGINT не игнорировался в скрипте (, например, когда скрипт запускался в фоновом режиме ), вы можете сделать:

#! /bin/sh -
(trap - INT QUIT; exec zenity) & wait

Чтобы восстановить расположение по умолчанию для SIGINT и SIGQUIT.

Тем не менее, хотя POSIX прямо говорит, что это должно работать , это не работает с некоторыми shреализациями. В частности, не с dashи большинством других производных ash, ksh93, boshили yash. Таким образом, вы можете изменить метку -на #! /bin/bash -, или #! /bin/zsh -, или #! /bin/mksh -, чтобы убедиться, что в этом случае у вас есть оболочка, совместимая с POSIX -.

Если SIGINT был проигнорирован при запуске оболочки, вам нужно будет использовать zshдля восстановления их расположения:

#! /bin/zsh -
trap : INT QUIT # noop handler to unignore
trap - INT QUIT # restore default disposition for the shell
(trap - INT QUIT; zenity) & wait

Пример (здесь, в Linux, где расположение сигналов представлено в виде растровых изображений в/proc/<pid>/status):

$ sh -c 'grep SigIgn /proc/self/status'
SigIgn: 0000000000000000
$ sh -c 'grep SigIgn /proc/self/status & wait'
SigIgn: 0000000000000006 # (1<<(SIGINT-1) | 1<<(SIGQUIT-1))

$ zsh -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000000
$ bash -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000000
$ mksh -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000000

$ dash -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000006
$ ksh93 -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000006
$ yash -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000000006
$ bosh -c '(trap - INT QUIT; exec grep SigIgn /proc/self/status) & wait'
SigIgn: 0000000000100006  # also SIGTTIN

$ (bash -c 'grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000006
$ (bash -c 'trap - INT QUIT; grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000006

$ (zsh -c 'grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000002 # not sure why the SIGQUIT was unignored
$ (zsh -c 'trap - INT QUIT; grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000002
$ (zsh -c 'trap : INT QUIT; trap - INT QUIT; grep SigIgn /proc/self/status' & wait)
SigIgn: 0000000000000000
2
27.01.2020, 21:17

Теги

Похожие вопросы