Level: Intermediate Adam Cormany (acormany@yahoo.com), National Data Center Manager, Scientific Games Corporation
01 Apr 2008 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.
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:
The current cursor location must be saved first. To save the current cursor
position, include the sc option, or "save
cursor position."
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.
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:
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
-
Participate in the AIX and UNIX forums:
About the author  | |  | While Adam Cormany is currently the Manager of the National Data Center,
he has also been an UNIX Systems Engineer, UNIX Administrator, and
Operations Manager for Scientific Games in the last few years. Adam has
worked heavily with AIX as well as 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. |
Rate this page
|