Предисловие
Моим первоначальным намерением было написать скрипт, который каждую секунду проверяет, какое оборудование (может быть, раковина лучше?) Играет Spotify musi c (наушники , стерео, ...) так что эта информация надежна даже после завершения Spotify (например, это идентификатор аппаратного Spotify, который использовался, когда он был закрыт ).
Сценарий, который я изначально написал для этого, по сути был сценарием, который вызывает и анализирует pactl list
в while true
l oop для получения #id оборудования, на котором Spotify воспроизводит аудио.
Это работало, пока работал Spotify, но когда Spotify был закрыт, конечным результатом этого "слушателя" была пустая строка, что показалось бы мне нормальным, если бы pactl info
был вызван после закрывая Spotify, но я подумал, что назвал это до .
На данный момент, я думаю, я мог неправильно понять, как обработка сигналов и trap
s работают в bash
.
М (не) МЫ * 10 26 * Чтобы дать себе и вам MWE, я придумал следующий сценарий: driver.sh
, который запускает сценарий listener.sh
в фоновом режиме и затем запускается Spotify не в фоновом режиме (насколько я понимаю, отправка сигнала в Spotify, например его закрытие, приводит к отправке этого сигнала на driver.sh
); он также устанавливает trap
, который завершает фоновый процесс. #!/bin/bash
trap 'kill -TERM $bg_pid' SIGINT SIGTERM EXIT
./listen.sh &
bg_pid=$!
echo "bg_pid: $bg_pid"
/usr/bin/spotify
A listener.sh
скрипт, который бесконечно анализирует вывод pactl list
для строки media.name
в while true
петля; trap
гарантирует, что синтаксический анализ выполняется в последний раз после завершения. #!/bin/bash
trap 'echo trap:; func; exit' SIGINT SIGTERM EXIT
func() {
echo func: $(pactl list | sed -E '/media\.name/p;d')
}
while true; do
func
sleep 1
done
Я думал, что при данной настройке извлечение driver.sh
из терминала приведет к следующему. Spotify открывается, и терминал заполняется, секунда за секундой, строками вида func: media.name = "Spotify"
func: media.name = "Spotify"
func: media.name = "Spotify"
...
При закрытии Spotify (убивая driver.sh
или закрываясь Окно Spotify) еще две строки: trap:
func: media.name = "Spotify"
Вместо этого я получу, если закрою Spotify: ...
func: media.name = "Spotify"
func: media.name = "Spotify"
+enrico:~$ trap:
func: # empty!
trap:
func: # why again?
Если вместо этого я CTRL + C driver.sh
Я понял (мои комментарии): ...
func: media.name = "Spotify"
func: media.name = "Spotify"
^Cfunc: media.name = "Spotify" # here I hit ctrl+c
func: media.name = "Spotify" # maybe this delay is because of sleep in listener.sh?
./spot.sh: line 6: 8704 Segmentation fault (core dumped) /usr/bin/spotify # why this SegV?
+enrico:~$ trap:
func: # empty!
trap:
func: # why again?
Меня это озадачивает. Я думал, что после получения сигнала завершения, driver.sh
должен захватить его с помощью trap
и запустить команду kill -TERM $bg_pid
, чтобы обработать его. В свою очередь, listener.sh
после получения сигнала должен выполнить echo
, затем func
, затем exit
. Только в этот момент Spotify должен прекратить работу. Если бы после звонка pactl list
после этого не было бы Spotify, я бы понял. Очевидно, я, возможно, неправильно все понял.