LINUX.ORG.RU

i3blocks. Выполнение команды в отдельном процессе

 , , ,


0

1

Использую связку i3wm+i3blocks.
В i3blocks стоит индикатор состояния плеера deadbeef (отдельным скриптом).
На индикаторе, помимо отображения, прикручена обработка событий для мыши — «колесо» крутит громкость, «клик» ставит на паузу/воспроизведение.

Всё работает, но есть момент.
Пауза/воспроизведение реализуется командой deadbeef --play-pause. Если эту команду выполнить в консоли при закрытом плеере, то плеер будет запущен.
Но вот из скрипта плеер запускается, но перестаёт обрабатываться индикатором. Т. е. плеер как будто запускается в каком-то подпроцессе. Кстати, если перезапустить оболочку i3wm, плеер будет выключен, в то время как если запустить его отдельной командой, он продолжает работать.

Соответственно вопрос, если я правильно понял проблему, как сделать, чтобы плеер запускался самостоятельным процессом?

Код индикатора:

#!/bin/bash

# иконки состояний
ICON_PLAY="[⏴]"
ICON_PAUSE="[⏸]"
ICON_STOP="проигрыватель остановлен [⏹]"
ICON_OFF="проигрыватель выключен [⏻]"
SONG=$(deadbeef --nowplaying-tf '%tracknumber%. %title% \ %playback_time% / %length%')

# проверить включена ли программа
if pidof deadbeef > /dev/null;
then STATE="10"
else STATE="20"
fi

# статус воспроизведения
if [ $(deadbeef --nowplaying-tf '%isplaying%') == "1" ];
then STATUS="3"
elif [ $(deadbeef --nowplaying-tf '%ispaused%') == "1" ];
then STATUS="4"
else STATUS="5"
fi

# вычислить общий статус
let "CALC = $STATE + $STATUS"

# отобразить состояние плеера
if [[ "$CALC" -eq "13" ]];
then echo "$SONG $ICON_PLAY"
elif [[ "$CALC" -eq "14" ]];
then echo "$SONG $ICON_PAUSE"
elif [[ "$CALC" -eq "15" ]];
then echo "$ICON_STOP"
elif [[ "$STATE" -eq "20" ]];
then echo "$ICON_OFF"
fi

case $BLOCK_BUTTON in
  # левым кликом поставить на паузу
  1) exec nohup deadbeef --play-pause && > /dev/null; exec pkill -SIGRTMIN+12 i3blocks ;;
  # средним кликом отключить звук
  2) ponymix toggle >/dev/null ;;
  # правым кликом передать фокус
  3) i3-msg workspace 4 ;;
  # Прокрутка вниз
  4) ponymix increase 5 >/dev/null; exec pkill -SIGRTMIN+10 i3blocks ;;
  # Прокрутка вниз
  5) ponymix decrease 5 >/dev/null; exec pkill -SIGRTMIN+10 i3blocks ;;
esac


Последнее исправление: Dreamdrawer (всего исправлений: 1)

я так понимаю, нужно как минимум добавить & после deadbeef --play-pause. так индикатор не будет подвисать. а если нужно, чтобы плеер ещё и не завершался при перезапуске, то используй nohup.

eternal_sorrow ★★★★★
()
Ответ на: комментарий от eternal_sorrow

Да, эти условия соблюдены, команда полностью выглядит так:
nohup deadbeef --play-pause && > /dev/null; exec pkill -SIGRTMIN+12 i3blocks ;;
почему-то nohup не помогает.

Dreamdrawer
() автор топика
Ответ на: комментарий от Dreamdrawer

exec nohup deadbeef –play-pause && > /dev/null; exec pkill -SIGRTMIN+12 i3blocks ;;

Два exec подряд? && != &. nohup + > /dev/null? Да что здесь происходит вообще?

Можно ещё так попробовать (возможно, что & не нужен):

1) setsid deadbeef --play-pause & ;;

Хотя основной бок скорее в &&.

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

Вообще не реагирует. Начинает работать только если убрать «&», но исходная проблема не решается.

Dreamdrawer
() автор топика

Решение

методом научного тыка нашёлся рабочий вариант:

1) i3-msg exec deadbeef > /dev/null; (nohup deadbeef --play-pause) ;;

без предварительного выполнения deadbeef > /dev/null; работать отказывается наотрез. Зачем это ему не понимаю.

В целом, задача решена, но буду признателен за поправки, объяснения или альтернативные предложения.

Dreamdrawer
() автор топика
Последнее исправление: Dreamdrawer (всего исправлений: 1)
Ответ на: Решение от Dreamdrawer

буду признателен за поправки, объяснения или альтернативные предложения

вроде как для deadbeef есть плагины с поддержкой MPRIS (например). Значит, им можно рулить по dbus с помощью playerctl, тогда точно не придется беспокоиться о подпроцессах.

anonymous
()
Ответ на: Решение от Dreamdrawer

Зачем это ему не понимаю.

первая команда запускает плеер, т.к. он еще не запущен. при этом плеер не детачится от родительского процесса, поэтому надо делать ‘&’ или ‘nohup’.

вторая посылает запущенному плееру команду play-pause и завершается. поэтому во второй команде ‘nohup’ уже не нужен.

правильнее будет проверять: если плеер не запущен: запустить; иначе play-pause.

waker ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.