Discover tput

Add some spice to your UNIX shell scripts

One of the strongest assets UNIX® has is the ability to make shell scripts to ease users' lives. These scripts can range from simple one-liners to several thousand lines. Many times, shell scripts evolve into menu-based scripts, and the scripter wants to display more to users than simply scrolling text. Other times, a simple line or two of output are displayed to users, and the shell scripter wants to put emphasis on a warning message. Regardless of the complexity, scripters have always needed a way to change their output to bold, underline it, reverse the highlights, and so on. That's where tput comes into play.

Adam Cormany, National Data Center Manager, Scientific Games Corporation

Adam Cormany is currently the manager of the National Data Center, but he has also been a UNIX systems engineer, a UNIX administrator, and operations manager for Scientific Games Corporation. Adam has worked extensively with AIX as well as in Solaris and Red Hat Linux administration for more than 10 years. He is an IBM eServer®-Certified Specialist in pSeries® AIX System Administration. In addition to administration, Adam has extensive knowledge of shell scripting in Bash, CSH, and KSH as well as programming in C, PHP, and Perl. You can reach Adam at acormany@yahoo.com.



01 April 2008

Also available in Chinese Russian Japanese

What is tput?

The tput command initializes and manipulates your terminal session through the terminfo database. Using tput, you can alter several terminal capabilities, such as moving or altering the cursor, changing text properties, and clearing specific areas of the terminal screen.


What is the terminfo database?

The terminfo database on a UNIX system defines terminal and printer attributes and capabilities, including the number of lines and columns for the respective device (for example, terminal and printer) and attributes of text to be sent to the device. Several commonly used programs in UNIX rely on the terminfo database for these attributes as well as many others, including the vi and emacs editors as well as the curses and man programs.


Command-line introduction to tput

The tput command, like most commands in UNIX, can be used either at your shell command line or inside a shell script. To gain a better understanding of tput, this article starts with the command line, and then continues into shell script examples.

Cursor attributes

Moving the cursor or altering its attributes can be helpful in UNIX shell scripts or at the command line. There may be times when you're required to enter sensitive information, such as a password, or enter information in two different areas of the screen. Using tput can help you in such conditions.

Moving the cursor

Moving the cursor’s position on the respective device is easily done with tput. Using the cup option, or cursor position, in tput, you can move the cursor to any X or Y coordinates in the device's rows and columns. The top left coordinates of the device are 0,0.

To move the cursor to the fifth column (X) and the first row (Y) on a device, simply execute tput cup 5 1. Another example would be tput cup 23 45, which would move the cursor to the forty-fifth row in the twenty-third column.

Moving the cursor and displaying information

Another useful cursor position trick is to move the cursor, execute a command to display information, and then return to the previous cursor location:

(tput sc ; tput cup 23 45 ; echo “Input from tput/echo at 23/45” ; tput rc)

Let’s break down the subshell commands:

tput sc

The current cursor location must be saved first. To save the current cursor position, include the sc option, or "save cursor position."

tput cup 23 45

After the cursor location has been saved, the cursor coordinates will be moved to 23,45.

echo “Input from tput/echo at 23/45”

Display information to stdout.

tput rc

When the information has been displayed, the cursor must return to the original location that was saved with tput sc. To return the cursor to its last saved location, include the rc option, or "restore cursor position."

Note: Because this article details command-line execution of tput first, it would be cleaner for you to execute the commands in your own subshell rather than executing each command separately and showing a prompt before each command execution.

Altering the cursor's attributes

When displaying data to a device, there are times when you don't want to see the cursor. Turning the cursor invisible creates a cleaner look when data is scrolling across the screen. To make the cursor invisible, use the civis option (for example, tput civis). When the data has been completely displayed, you can make the cursor visible again by using the cnorm option.

Text attributes

Changing how text is shown can bring attention to a set of words in a menu or alert users to something important. You can change text attributes such as making the text bold, placing an underline under the text, changing the background and foreground colors, as well as reversing the color scheme.

To change the color of the text, use the setb option for setting the background color and the setf option for setting the foreground color along with the number of the color assigned in the terminfo database. The following numbers and colors are typically assigned but may vary from each UNIX system:

  • 0: Black
  • 1: Blue
  • 2: Green
  • 3: Cyan
  • 4: Red
  • 5: Magenta
  • 6: Yellow
  • 7: White

Executing these sample commands changes the background color to yellow and the foreground to red:

tput setb 6
tput setf 4

To reverse the current color scheme, simply execute tput rev.

Sometimes, adding color to text isn't enough, or you would rather draw the user's attention another way. Two ways to accomplish this would be to set the text to bold with underline.

To change the text to be bold, use the bold option. To begin underlining, use the smul option. When you're finished displaying the underlined text, use the rmul option.


Taking your shell script to the next level

Now that you know the basics of tput from the command line, it's time to focus on putting what you've learned into a shell script along with some other features. First, here are some additional features that tput provides: extracting terminal information such as the devices, the number of columns and rows, and clearing data from the screen.

To determine the current number of columns or the width that you can use on the target device, you use the cols option. To find the number of rows or their current height, use the lines option.

You can clear data in a few ways, depending on the result you need. To clear data from the current cursor position the end of a line, you use tput el. To clear data from the current cursor position to the end of the device, you use tput ed. If you want to clear the entire device, use tput clear.

Putting it all together in a script

The following code creates a basic menu. The script introduces how you can use many of the options in tput explained in this article to enhance your coding.

 #!/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

Let's break down the shell script.

Set how the script will be interpreted. In this case, the shell to be used is Bash. Set a trap for the WINCH signal as well, and assign the get_window_size function to be the trigger of the trapped signal. After the trap has been set, define two variables to ease the typing later in the script.

#!/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

Create a function named get_widow_size to determine the number of rows and columns. In addition, define the _FULL_UNDERLINE variable with an underline the width of the device (columns).

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
}

Create a function named set_color to allow users to test background and foreground text colors.

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
}

Create a function named show_menu that demonstrates the size of the device. Also demonstrated in this function are turning the cursor invisible, clearing the screen, printing text, and returning to the saved cursor location.

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
}

Next, set some basic cursor attributes. First, all attributes are cleared with sgr0. The cursor is turned invisible, and the screen is cleared. The invisible cursor is now moved to 3,10, the location is saved, and then the cursor is moved to 0,0 (top left).

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

Finally, call the function get_window_size to get the windows size and, in return, call the function show menu.

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

exit 0

Conclusion

Introducing tput into shell scripts in UNIX can enhance the look and feel of scripts. There are hundreds of ways to accomplish a task in UNIX, so why not add some color and a professional look to it? Learning tput is easy and can be very effective for scripts; users will appreciate the benefits behind controlling the look of a screen more. This article is only the beginning of what you can do with tput. With tput and a bit of work, you can create a full-blown, menu-driven shell script that will look great!

Resources

Learn

Get products and technologies

  • IBM trial software: Build your next development project with software for download directly from developerWorks.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into AIX and Unix on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=AIX and UNIX, Linux
ArticleID=298823
ArticleTitle=Discover tput
publish-date=04012008