The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
.
google unix.com



Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts and shell scripting languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
SunOS 5.10 - VI Arrow keys not working ravashingravi UNIX for Dummies Questions & Answers 7 12-01-2008 11:22 AM
command scrolling using arrow keys hemangi13 UNIX and Linux Applications 4 09-11-2008 01:53 PM
Using arrow keys cooldude SUN Solaris 4 06-13-2008 12:51 PM
arrow keys / special keys raguramtgr UNIX for Dummies Questions & Answers 3 02-20-2004 02:45 AM
Trapping Arrow keys nageshrc Shell Programming and Scripting 1 11-30-2001 03:36 PM

Closed Thread
English Japanese Spanish French German Portuguese Italian Dutch Swedish Russian Norwegian Hungarian Hebrew Danish Bulgarian Greek Powered by Powered by Google
 
LinkBack Thread Tools Search this Thread Rate Thread Display Modes
  #1 (permalink)  
Old 05-22-2009
cambridge cambridge is offline
Registered User
  
 

Join Date: May 2009
Posts: 55
Using arrow keys in shell scripts

I recently needed to collect arrow keys (and function keys etc.) in a shell script so that I could run a text graphics-style data entry system (with text entry fields, drop-down list boxes, progress bars and the like). Yes you can do all this in shell, and portably too if you're careful.

I've seen others asking how to capture keypresses in shell scripts in the past, with a variety of responses from other people, so thought you might all like to see a little mock-up program that catches keypresses and reports the key that was pressed. This has been tested in Solaris, Linux (SuSE) and AIX. It's written in ksh just because I like it, but would equally work in bash if you changed the 'print' commands to 'echo'. The script reports 10 keypresses in octal and then exits. Note the use of 'tput' to determine the correct terminal codes.

Enjoy.

Code:
#!/bin/ksh
AWK=gawk
[ -x /bin/nawk ] && AWK=nawk
ECHO="print"
ECHO_N="print -n"

tty_save=$(stty -g)

function Get_odx
{
    od -t o1 | $AWK '{ for (i=2; i<=NF; i++)
                        printf("%s%s", i==2 ? "" : " ", $i)
                        exit }'
}

# Grab terminal capabilities
tty_cuu1=$(tput cuu1 2>&1 | Get_odx)            # up arrow
tty_kcuu1=$(tput kcuu1 2>&1 | Get_odx)
tty_cud1=$(tput cud1 2>&1 | Get_odx)            # down arrow
tty_kcud1=$(tput kcud1 2>&1 | Get_odx)
tty_cub1=$(tput cub1 2>&1 | Get_odx)            # left arrow
tty_kcub1=$(tput kcud1 2>&1 | Get_odx)
tty_cuf1=$(tput cuf1 2>&1 | Get_odx)            # right arrow
tty_kcuf1=$(tput kcud1 2>&1 | Get_odx)
tty_ent=$($ECHO | Get_odx)                      # Enter key
tty_kent=$(tput kent 2>&1 | Get_odx)
tty_bs=$($ECHO_N "\b" | Get_odx)                # Backspace key
tty_kbs=$(tput kbs 2>&1 | Get_odx)

# Some terminals (e.g. PuTTY) send the wrong code for certain arrow keys
if [ "$tty_cuu1" = "033 133 101" -o "$tty_kcuu1" = "033 133 101" ]; then
    tty_cudx="033 133 102"
    tty_cufx="033 133 103"
    tty_cubx="033 133 104"
fi

stty cs8 -icanon -echo min 10 time 1
stty intr '' susp ''

trap "stty $tty_save; exit"  INT HUP TERM

count=0
while :; do
    [ $count -eq 10 ] && break
    count=$((count+1))

    keypress=$(dd bs=10 count=1 2> /dev/null | Get_odx)

    $ECHO_N "keypress=\"$keypress\""

    case "$keypress" in
        "$tty_ent"|"$tty_kent") $ECHO " -- ENTER";;
        "$tty_bs"|"$tty_kbs") $ECHO " -- BACKSPACE";;
        "$tty_cuu1"|"$tty_kcuu1") $ECHO " -- KEY_UP";;
        "$tty_cud1"|"$tty_kcud1"|"$tty_cudx") $ECHO " -- KEY_DOWN";;
        "$tty_cub1"|"$tty_kcub1"|"$tty_cubx") $ECHO " -- KEY_LEFT";;
        "$tty_cuf1"|"$tty_kcuf1"|"$tty_cufx") $ECHO " -- KEY_RIGHT";;
        *) $ECHO;;
    esac
done

stty $tty_save
Bits Awarded / Charged to cambridge for this Post
Date User Comment Amount
05-22-2009 Neo Thanks for the code! 3,000
  #2 (permalink)  
Old 05-25-2009
otheus's Avatar
otheus otheus is offline Forum Staff  
Moderator ala Mode
  
 

Join Date: Feb 2007
Location: Innsbruck, Austria
Posts: 1,886
Pretty cool. Uh just a comment: ksh also works with "echo". No need to anonymize this command.
  #3 (permalink)  
Old 05-26-2009
cambridge cambridge is offline
Registered User
  
 

Join Date: May 2009
Posts: 55
The 'echo' command is not normally a ksh built-in. This means that not only are the options system-dependent (and I needed code that worked reliably on numerous platforms), but it will also spawn a new process which will slow your code down. The 'print' command is built-in to the shell and does not suffer these problems. I would always recommend people use 'print' instead of 'echo' when using ksh.
  #4 (permalink)  
Old 05-26-2009
otheus's Avatar
otheus otheus is offline Forum Staff  
Moderator ala Mode
  
 

Join Date: Feb 2007
Location: Innsbruck, Austria
Posts: 1,886
The man pages say that echo is indeed a builtin:
Quote:
echo [-neE] [arg ...]
Prints its arguments (separated by spaces) followed by a newline, to standard out. The newline is suppressed if any of the arguments contain the backslash sequence \c. See print command below for a list of other backslash sequences that are recognized.
The options are provided for compatibility with BSD shell scripts: -n suppresses the trailing newline, -e enables backslash interpretation (a no-op, since this is normally done), and -E which suppresses backslash interpretation.
Further evidence:
Code:
root@sf8 # uname -a
SunOS sf8 5.10 Generic_127127-11 sun4u sparc SUNW,SPARC-Enterprise
root@sf8 # echo $0
/usr/bin/ksh
root@sf8 # type echo
echo is a shell builtin
  #5 (permalink)  
Old 05-26-2009
cambridge cambridge is offline
Registered User
  
 

Join Date: May 2009
Posts: 55
Yes, but it doesn't have to be a built-in. From the ksh man page on SuSE:

Quote:
echo [ arg ... ]
When the first arg does not begin with a -, and none of the
arguments contain a \, then echo prints each of its arguments
separated by a space and terminated by a new-line. Otherwise,
the behavior of echo is system dependent and print or printf
described below should be used.
If I want to write a ksh script that has maximum portability, especially when I want to use certain options (e.g. -e or -r), I do not want to be using 'echo'.
Closed Thread

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -4. The time now is 09:09 PM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited. Language Translations Powered by .
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios
The UNIX and Linux Forums Content Copyright ©1993-2009. All Rights Reserved.Ad Management by RedTyger

Content Relevant URLs by vBSEO 3.2.0