Problema com o sinal WINCH - o que estou negligenciando?

3

Estou tendo um problema com o sinal WINCH no código a seguir, que é de um tutorial localizado em developerWorks® :

#!/bin/bash
trap 'get_window_size' WINCH                    # trap when a user has resized the window

_UNDERLINE_ON='tput smul'                       # turn on underline
_UNDERLINE_OFF='tput rmul'                      # turn off underline

get_window_size() {
  _WINDOW_X='tput lines'
  _WINDOW_Y='tput cols'

  _FULL_SPACES='echo ""|awk '
  {
    _SPACES = '${_WINDOW_Y}'
    while (_SPACES-- > 0) printf (" ")
  }''
  _FULL_UNDERLINE='echo "${_UNDERLINE_ON}${_FULL_SPACES}${_UNDERLINE_OFF}"'

  unset _FULL_SPACES
  show_menu

  return 0
}

set_color() {
  tput clear
  PS3="Enter Selection[1-9]:"
  select _COLOR in "Black" "Blue" "Green" "Cyan" "Red" "Magenta" "Yellow" "White" "Exit"
  do
    case ${REPLY} in
       [1-8])  _X='expr ${REPLY} - 1';;
           9)  break;;
           *)  echo "Invalid Color"; continue;;
    esac

    if [[ ${1} = "b" ]]
    then
      tput setb ${_X}
        else
      tput setf ${_X}
    fi
  done
}

show_menu() {
  while [[ -z ${_ANS} ]]
  do
    tput civis
    tput clear

    cat <<- EOF
Window Size: ${_WINDOW_X} / ${_WINDOW_Y}


Select => ${_UNDERLINE_ON}     ${_UNDERLINE_OFF}

${_FULL_UNDERLINE}
B) Background Text Color
F) Foreground Text Color

X) Exit
EOF

    tput rc
    tput smul
    tput cnorm

    read _ANS
    tput rmul

    case ${_ANS} in
      [Bb])  set_color "b";;
      [Ff])  set_color "f";;
      [Xx])  tput clear; exit;;
         *)
             echo -e "Invalid Selection: ${_ANS}\c"
             sleep 2
             ;;
    esac
    unset _ANS
  done
}

tput sgr0
tput civis
tput clear
tput cup 3 10
tput sc
tput cup 0 0

[[ -n ${_ANS} ]] && unset _ANS
get_window_size

exit 0

Como estou bloqueando o sinal WINCH (mudança de janela) , espero que (toda vez que eu ajuste a janela que contém este script em execução) a função get_window_size será invocada.

No entanto, na minha máquina, ele apenas captura o sinal WINCH uma vez (sob condições específicas). A armadilha acontece somente se eu usar o menu xterm (neste caso, gnome-terminal) Terminal para escolher um dos tamanhos padrão (80x24, 80x43, 132x24, 132x43); Além disso, acontece apenas o primeiro tempo. Se eu alterar posteriormente o tamanho da janela (usando o item de menu Terminal ), nenhuma trapping ocorrerá.

Além disso, se eu não usar o item de menu Terminal , mas redimensionar usando um dispositivo apontador, até mesmo a primeira armadilha não acontecerá.

Alguém pode me ajudar a entender o que está errado (seja com o código ou com a minha expectativa)?

    
por TheGeeko61 11.01.2012 / 04:12

1 resposta

3

Eu suspeito que há algo de bobo na forma como o script aguarda por uma ação do usuário e / ou um sinal. Observe que get_window_size chama show_menu , que é o que aguarda a entrada do usuário ( read _ANS ).

O comando trap também faz com que get_window_size seja chamado pelo SIGWINCH. Não sei se as funções do shell são reentrantes ou não.

Minhas expectativas de como o SIGWINCH deve ser gerado, e quando a função de armadilha deve ser executada, são basicamente as mesmas que as suas. Eu cortei o script de exemplo um pouco, e fiz isso não reentrante. Veja abaixo.

Você também pode considerar tentar seu script com um gerenciador de janelas diferente. Eu usei o venerável, rápido e altamente configurável twm no meu experimento.

#!/bin/bash
trap 'get_window_size' WINCH                    # trap when a user has resized the window
get_window_size() {
        _WINDOW_X='tput lines'
        _WINDOW_Y='tput cols'

        echo "X: $_WINDOW_X"
        echo "Y: $_WINDOW_Y"

        return 0
}

while read ALINE
do
        echo "Read: '$ALINE'"
done
    
por 11.01.2012 / 06:02

Tags