I am having an issue with the WINCH signal in the following code which is from a tutorial located at developerWorks®:

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 (" ")

  unset _FULL_SPACES

  return 0

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

    if [[ ${1} = "b" ]]
      tput setb ${_X}
      tput setf ${_X}

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

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

Select => ${_UNDERLINE_ON}     ${_UNDERLINE_OFF}

B) Background Text Color
F) Foreground Text Color

X) Exit

    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
    unset _ANS

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

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

exit 0

Since I am trapping the WINCH (window change) signal, I expect that (each time I adjust the window which contains this running script) the get_window_size function will be invoked.

However, on my machine, it only traps the WINCH signal once (under specific conditions). The trap happens only if I use the xterm (in this case, gnome-terminal) Terminal menu to choose one of the default sizes (80x24, 80x43, 132x24, 132x43); further, it happens only the first such time. If I subsequently change the window size (using the Terminal menu item), no trapping occurs.

Also, if I don't use the Terminal menu item, but re-size using a pointing device, even the first trap does not happen.

Can someone help me to understand what is wrong (either with the code or with my expectation)?


I suspect there's something goofy in the way the script waits for a user action and/or a signal. Note that get_window_size calls show_menu, which is what waits for user input (read _ANS).

The trap command also causes get_window_size to be called by the SIGWINCH. I don't know if shell functions are re-entrant or not.

My expectations of how SIGWINCH should get generated, and when the trap function should get executed are basically the same as yours. I cut down the example script a bit, and made it non-reentrant. See below.

You may also want to consider trying your script with a different window manager. I used the venerable, speedy and highly configurable twm in my experiment.

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
        echo "Read: '$ALINE'"
| improve this answer | |
  • Essentially, you were on to something in raising the re-entrancy question. I removed the call to show_menu from the get_window_size function and simply placed a call to show_menu beneath the call to get_window_size in the main section. This, indeed, resolves the issue! Thank you for your input! – TheGeeko61 Jan 11 '12 at 6:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.