Прочитал статью про сигналы Медведя и захотелось немного разобраться в теме. Немного переписал проги, чтобы можно было от клиента к серверу передавать любые сообщения в виде текста.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Алгоритм простой. Используем 10 сигналов (SIGRTMIN+0 - SIGRTMIN+7 для передачи битов, SIGRTMIN+8 - признак окончания символа, SIGRTMIN+9 признак окончания сообщения).

Передаются только "единичные биты". SEND_CHAR - "разбирает символ по битам и передает" SEND_MESSAGE - разбирает сообщение по символам и отдает SEND_CHAR.

Сохраняем скрипты, chmod +x serv.sh cli.sh

В одном терминале ./serv.sh (он выдаст что-то вроде Listener process 340527).

В другом терминале ./cli.sh 340527 (нужно подставить ваш номер процесса).

При старте клиент сразу передает серверу сообщение "BashBays" А потом можете передать привет медведю. Пустое сообщение завершает клиента. Сервер останавливается через CTRL-C.

#/bin/bash

#serv.sh

declare -i ASC=0
declare MSG=
declare DELAY=0.01
handle_signal() {
  case "$1" in
    W) MSG=${MSG}$(printf "\x$(printf %x $ASC)")
       ASC=0 ;;
    M) echo $MSG;MSG=;;
    *) ((ASC+=$1));;
  esac
}
#RTMIN=34
trap 'handle_signal 1' RTMIN+0
trap 'handle_signal 2' RTMIN+1
trap 'handle_signal 4' RTMIN+2
trap 'handle_signal 8' RTMIN+3
trap 'handle_signal 16' RTMIN+4
trap 'handle_signal 32' RTMIN+5
trap 'handle_signal 64' RTMIN+6
trap 'handle_signal 128' RTMIN+7
trap 'handle_signal W' RTMIN+8
trap 'handle_signal M' RTMIN+9
echo Listener process $$
while :;do
  sleep $DELAY
done
#!/bin/bash

#cli.sh

if [[ -z $1 ]];then
  echo Need server PID
  exit
fi
declare -ir SERV_PID=$1
declare MESSAGE=BashBays
declare -ir RTM=34

function DELAY(){ sleep 0.02;}

function SEND_CHAR(){
  local -i i ASC
  CUR_CHAR=${1:-" "}
  printf -v ASC "%d" "'$CUR_CHAR"
  for i in {0..7};do
    if [[  $(($ASC%2)) -eq 1 ]];then
#     echo kill '-'$(($i+$RTM)) $SERV_PID
      kill '-'$(($i+$RTM)) $SERV_PID
      DELAY
    fi
    ((ASC/=2))
  done
# echo kill '-'$((8+$RTM)) $SERV_PID
  kill '-'$((8+$RTM)) $SERV_PID
  DELAY
}
function SEND_MESSAGE(){
  local CUR_CHAR
  local MESSAGE=${1:-BashDays}
  local i
  echo  Send message \"$MESSAGE\" to  Server PID=$SERV_PID
  for ((i = 0 ; i < ${#MESSAGE} ; i++));do
    SEND_CHAR ${MESSAGE:$i:1}
  done
# echo kill '-'$((9+$RTM)) $SERV_PID
  kill '-'$((9+$RTM)) $SERV_PID
  DELAY
}

while [[ $MESSAGE ]];do
  SEND_MESSAGE "$MESSAGE"
  read  -p "Input new message:" MESSAGE
done

Для чего может пригодиться эта фигня я не знаю, Но при написании программы выяснил некоторые вещи:

  1. Обработка сигналов (по крайней мере SIGRTMIN не прерывает выполнение команд bash). Т.е если выполняется sleep 10m. То обработки можно ждать долго.
Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
  1. Обратите внимания на задержки в программах. На сервере ввел задержку, чтобы не сильно грузить процессор, на клиенте задержка больше, чем на сервере, иначе сигналы могут теряться. Кому интересно - можете поиграться.