source: vendor/bash/3.1-p17/examples/scripts/line-input.bash

Last change on this file was 3228, checked in by bird, 18 years ago

bash 3.1

File size: 4.5 KB
Line 
1#! /bin/bash
2#
3#From: kaz@cafe.net (Kaz Kylheku)
4#Newsgroups: comp.unix.shell
5#Subject: Funky little bash script
6#Message-ID: <6mspb9$ft2@espresso.cafe.net>
7#Date: Thu, 25 Jun 1998 06:11:39 GMT
8
9#Here is something I wrote a few years ago when I was bored one day.
10#Warning: this contains control characters.
11
12# Line input routine for GNU Bourne-Again Shell
13# plus terminal-control primitives.
14#
15# by Kaz Kylheku
16# June 1996, Vancouver, Canada
17
18
19#
20# Function to disable canonical input processing.
21# Terminal modes are saved into variable "savetty"
22#
23#
24
25function raw
26{
27 savetty=$(stty -g)
28 stty -icanon -isig -echo -echok -echonl inlcr
29}
30
31#
32# Function to restore terminal settings from savetty variable
33#
34
35function restore
36{
37 stty $savetty
38}
39
40#
41# Set terminal MIN and TIME values.
42# If the input argument is a zero, set up terminal to wait for
43# a keystroke indefinitely. If the argument is non-zero, set up
44# an absolute timeout of that many tenths of a second. The inter-keystroke
45# timer facility of the terminal driver is not exploited.
46#
47
48function settimeout
49# $1 = tenths of a second
50{
51 if [ "$1" = "0" ] ; then
52 min=1
53 timeout=0
54 else
55 min=0
56 timeout="$1"
57 fi
58
59 stty min $min time $timeout
60
61 unset min timeout
62}
63
64#
65# Input a single key using 'dd' and echo it to standard output.
66# Launching an external program to get a single keystroke is a bit
67# of a pig, but it's the best you can do! Maybe we could convince the
68# GNU guys to make 'dd' a bash builtin.
69#
70
71function getkey
72{
73 eval $1="\"\$(dd bs=1 count=1 2> /dev/null)\""
74}
75
76#
77# Input a line of text gracefully.
78# The first argument is the name of a variable where the input line is
79# to be stored. If this variable is not empty, its contents are printed
80# and treated as though the user had entered them.
81# The second argument gives the maximum length of the input line; if it
82# is zero, the input is unlimited (bad idea).
83# ^W is used to delete words
84# ^R redraws the line at any time by backspacing over it and reprinting it
85# ^U backspaces to the beginning
86# ^H or ^? (backspace or del) delete a single character
87# ^M (enter) terminates the input
88# all other control keys are ignored and cause a beep when pressed
89#
90#
91
92
93function getline
94{
95 settimeout 0 # No keystroke timeout.
96 save_IFS="$IFS" # Save word delimiter and set it to
97 IFS="" # to null so ${#line} works correctly.
98 eval line=\${$1} # Fetch line contents
99 echo -n "$line" # and print the existing line.
100 while [ 1 ] ; do
101 getkey key # fetch a single keystroke
102 case "$key" in
103 |  ) # BS or DEL
104 if [ ${#line} != 0 ] ; then # if line not empty
105 echo -n " " # print destructive BS
106 line="${line%%?}" # chop last character
107 else # else if line empty
108 echo -n # beep the terminal
109 fi
110 ;;
111 ) # kill to line beg
112 while [ ${#line} != 0 ] ; do # while line not empty
113 echo -n " " # print BS, space, BS
114 line="${line%?}" # shorten line by 1
115 done
116 ;;
117 ) # redraw line
118 linesave="$line" # save the contents
119 while [ ${#line} != 0 ] ; do # kill to line beg
120 echo -n " "
121 line="${line%?}"
122 done
123 echo -n "$linesave" # reprint, restore
124 line="$linesave"
125 unset linesave # forget temp var
126 ;;
127 )
128 while [ "${line% }" != "$line" ] && [ ${#line} != 0 ] ; do
129 echo -n " "
130 line="${line%?}"
131 done
132 while [ "${line% }" = "$line" ] && [ ${#line} != 0 ] ; do
133 echo -n " "
134 line="${line%?}"
135 done
136 ;;
137  | | | | | | | | |
138 |
139 |
140 )
141 echo -n # ignore various control characters
142 ;; # with an annoying beep
143 | | | | | | | | | | | | )
144 echo -n
145 ;;
146 ' ' | |
147 |
148 | |
149 )
150 echo -n
151 ;;
152 '' ) # Break out of loop on carriage return.
153 echo # Send a newline to the terminal.
154 break # (Also triggered by NUL char!).
155 ;;
156 * ) # Append character to the end of the line.
157 # If length is restricted, and the line is too
158 # long, then beep...
159
160 if [ "$2" != 0 ] && [ $(( ${#line} >= $2 )) = 1 ] ; then
161 echo -n
162 else # Otherwise add
163 line="$line$key" # the character.
164 echo -n "$key" # And echo it.
165 fi
166 ;;
167 esac
168 done
169 eval $1=\"\$line\"
170 IFS="$save_IFS"
171 unset line save_IFS
172}
173
174# uncomment the lines below to create a standalone test program
175#
176echo "Line input demo for the GNU Bourne-Again Shell."
177echo "Hacked by Kaz Kylheku"
178echo
179echo "Use ^H/Backspace/Del to erase, ^W to kill words, ^U to kill the"
180echo "whole line of input, ^R to redraw the line."
181echo "Pass an argument to this program to prime the buffer contents"
182raw
183echo -n "go: "
184if [ ${#1} != 0 ] ; then
185 LINE=$1
186fi
187getline LINE 50
188restore
189
190echo "<$LINE>"
Note: See TracBrowser for help on using the repository browser.