📄 ch45_32.htm
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 45] 45.32 A Better read Command: grabchars </TITLE><METANAME="DC.title"CONTENT="UNIX Power Tools"><METANAME="DC.creator"CONTENT="Jerry Peek, Tim O'Reilly & Mike Loukides"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1998-08-04T21:55:12Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-260-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch45_01.htm"TITLE="45. Shell Programming for the Initiated"><LINKREL="prev"HREF="ch45_31.htm"TITLE="45.31 Nested Command Substitution "><LINKREL="next"HREF="ch45_33.htm"TITLE="45.33 Testing Two Strings with One case Statement "></HEAD><BODYBGCOLOR="#FFFFFF"TEXT="#000000"><DIVCLASS="htmlnav"><H1><IMGSRC="gifs/smbanner.gif"ALT="UNIX Power Tools"USEMAP="#srchmap"BORDER="0"></H1><MAPNAME="srchmap"><AREASHAPE="RECT"COORDS="0,0,466,58"HREF="index.htm"ALT="UNIX Power Tools"><AREASHAPE="RECT"COORDS="467,0,514,18"HREF="jobjects/fsearch.htm"ALT="Search this book"></MAP><TABLEWIDTH="515"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_31.htm"TITLE="45.31 Nested Command Substitution "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.31 Nested Command Substitution "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1">Chapter 45<BR>Shell Programming for the Initiated</FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_33.htm"TITLE="45.33 Testing Two Strings with One case Statement "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 45.33 Testing Two Strings with One case Statement "BORDER="0"></A></TD></TR></TABLE> <HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-7916">45.32 A Better read Command: grabchars </A></H2><TABLECLASS="para.programreference"BORDER="1"><TR><THVALIGN="TOP"><ACLASS="programreference"HREF="examples/index.htm"TITLE="grabchars">grabchars</A><BR></TH><TDVALIGN="TOP"><ACLASS="indexterm"NAME="AUTOID-54921"></A><ACLASS="indexterm"NAME="AUTOID-54924"></A><ACLASS="indexterm"NAME="AUTOID-54926"></A><ACLASS="indexterm"NAME="AUTOID-54929"></A><EMCLASS="emphasis">grabchars</EM> gets characters from the user as they aretyped in, without having to wait for the RETURN key tobe pressed.Among other things, this allows shell scriptsto be written with highly interactive menus.</TD></TR></TABLE><PCLASS="para">By default,<EMCLASS="emphasis">grabchars</EM>will obtain one character from the standard input, echo that character tothe standard output, and return an<SPANCLASS="link">exit status (<ACLASS="linkend"HREF="ch44_07.htm"TITLE="Exit Status of UNIX Processes ">44.7</A>)</SPAN>of one - meaning one character was read.Options (see the manual page) accept more than one character, acceptonly certain characters, prompt the user, and more.</P><PCLASS="para">Here's an example.With the standard<SPANCLASS="link"><EMCLASS="emphasis">echo</EM> (<ACLASS="linkend"HREF="ch08_06.htm"TITLE="Output Command-Line Arguments ">8.6</A>)</SPAN>and<SPANCLASS="link"><EMCLASS="emphasis">read</EM> (<ACLASS="linkend"HREF="ch44_13.htm"TITLE="read: Reading from the Keyboard ">44.13</A>)</SPAN>commands, you'd prompt a user this way:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">echo -n "Answer y or n, then press RETURN: "read ans</PRE></BLOCKQUOTE></P><PCLASS="para">With <EMCLASS="emphasis">grabchars</EM>,a prompt can be printed to standard error,the user's answer read as soon as the character is pressed, and<SPANCLASS="link">backquotes (<ACLASS="linkend"HREF="ch09_16.htm"TITLE="Command Substitution ">9.16</A>)</SPAN>used to grab the standard output (the user's answer, echoed by <EMCLASS="emphasis">grabchars</EM>):</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">ans=`grabchars -q'Answer y or n: '`</PRE></BLOCKQUOTE></P><PCLASS="para">By default, the answer that <EMCLASS="emphasis">grabchars</EM> reads and echoeswill be "eaten" by the backquotes; the user won't see what she typed.That's nice when the answer needs to be a secret.To show the answer, you have two choices:</P><ULCLASS="itemizedlist"><LICLASS="listitem"><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54953"></A>You can use the <EMCLASS="emphasis">-b</EM> option.<EMCLASS="emphasis">grabchars</EM> will echo the answer to both <EMCLASS="emphasis">stdout</EM> (which thebackquotes read) and <EMCLASS="emphasis">stderr</EM> (which is usually the terminal).</P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54962"></A>You can also use one of my favorite tricks, completing the user'sanswer before their eyes.For example, if the user types <CODECLASS="userinput"><B>y</B></CODE>, the script echoes <CODECLASS="literal">yes</CODE>.An <CODECLASS="userinput"><B>n</B></CODE> answer echoes as <CODECLASS="literal">no</CODE>.Any other answer (<EMCLASS="emphasis">x</EM>) echoes as:<CODECLASS="replaceable"><I>x</I></CODE><CODECLASS="literal">?</CODE> <CODECLASS="literal">Please</CODE> <CODECLASS="literal">answer</CODE> <CODECLASS="literal">y</CODE> <CODECLASS="literal">or</CODE><CODECLASS="literal">n</CODE>.Here's that sample code, including a<SPANCLASS="link"><EMCLASS="emphasis">while</EM> loop (<ACLASS="linkend"HREF="ch44_10.htm"TITLE="Loops That Test Exit Status ">44.10</A>)</SPAN>to repeat until the user types the right answer:</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54979"></A><TABLECLASS="screen.co"BORDER="1"><TR><THVALIGN="TOP"><PRECLASS="calloutlist"><ACLASS="co"HREF="ch45_09.htm"TITLE='45.9 The Unappreciated Bourne Shell ":" Operator'>:</A> <ACLASS="co"HREF="ch08_06.htm"TITLE="8.6 Output Command-Line Arguments ">1>&2</A> <ACLASS="co"HREF="ch45_09.htm"TITLE='45.9 The Unappreciated Bourne Shell ":" Operator'>break</A> </PRE></TH><TDVALIGN="TOP"><PRECLASS="screen">while :do ans=`grabchars -q'Answer y or n: '` case "$ans" in<ACLASS="indexterm"NAME="AUTOID-54984"></A>y) echo "yes" 1>&2; break ;; n) echo "no" 1>&2; break ;; *) echo "${ans}? Please answer y or n." 1>&2 ;; esacdone</PRE></TD></TR></TABLE></P></LI></UL><PCLASS="para">The option <CODECLASS="literal">-c</CODE><CODECLASS="replaceable"><I>valid-characters</I></CODE> tells <EMCLASS="emphasis">grachars</EM> toaccept only characters listed in <EMCLASS="emphasis">valid-characters</EM> (this can be aregular expression like <CODECLASS="literal">[a-z]</CODE>).If the user types something that isn't listed, <EMCLASS="emphasis">grabchars</EM> will ignorethe answer and wait.So, to accept only <EMCLASS="emphasis">y</EM> or <EMCLASS="emphasis">n</EM>:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">ans=`grabchars -c'yn' -q'Answer y or n: '`</PRE></BLOCKQUOTE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-55001"></A><ACLASS="indexterm"NAME="AUTOID-55004"></A>There are lots of other options.I'd like to explain two more.(Please look at the manual page for the rest.)You can give <EMCLASS="emphasis">grabchars</EM> a time limit with the<EMCLASS="emphasis">-t</EM> option.If the user doesn't answer bythen, <EMCLASS="emphasis">grabchars</EM> can quit - and also give a default answer from the<EMCLASS="emphasis">-d</EM> option.The timeout option lets you write shell scripts where you can offer someassistance if it's obvious that the user might be stuck - or to let a useranswer a prompt only if he doesn't want the default.For example:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">ans=`grabchars -t5 -d'y' -q'To stop, type n within 5 seconds: '`</PRE></BLOCKQUOTE></P><PCLASS="para">If the user doesn't type anything in 5 seconds, <EMCLASS="emphasis">grabchars</EM> willanswer <EMCLASS="emphasis">y</EM> automatically.</P><DIVCLASS="sect1info"><PCLASS="SECT1INFO">- <SPANCLASS="authorinitials">JP</SPAN>, <SPANCLASS="authorinitials">DS</SPAN></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="515"TITLE="footer"><TABLEWIDTH="515"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_31.htm"TITLE="45.31 Nested Command Substitution "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.31 Nested Command Substitution "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><ACLASS="book"HREF="index.htm"TITLE="UNIX Power Tools"><IMGSRC="gifs/txthome.gif"SRC="gifs/txthome.gif"ALT="UNIX Power Tools"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_33.htm"TITLE="45.33 Testing Two Strings with One case Statement "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 45.33 Testing Two Strings with One case Statement "BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">45.31 Nested Command Substitution </TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><ACLASS="index"HREF="index/idx_0.htm"TITLE="Book Index"><IMGSRC="gifs/index.gif"SRC="gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172">45.33 Testing Two Strings with One case Statement </TD></TR></TABLE><HRALIGN="LEFT"WIDTH="515"TITLE="footer"><IMGSRC="gifs/smnavbar.gif"SRC="gifs/smnavbar.gif"USEMAP="#map"BORDER="0"ALT="The UNIX CD Bookshelf Navigation"><MAPNAME="map"><AREASHAPE="RECT"COORDS="0,0,73,21"HREF="../index.htm"ALT="The UNIX CD Bookshelf"><AREASHAPE="RECT"COORDS="74,0,163,21"HREF="index.htm"ALT="UNIX Power Tools"><AREASHAPE="RECT"COORDS="164,0,257,21"HREF="../unixnut/index.htm"ALT="UNIX in a Nutshell"><AREASHAPE="RECT"COORDS="258,0,321,21"HREF="../vi/index.htm"ALT="Learning the vi Editor"><AREASHAPE="RECT"COORDS="322,0,378,21"HREF="../sedawk/index.htm"ALT="sed & awk"><AREASHAPE="RECT"COORDS="379,0,438,21"HREF="../ksh/index.htm"ALT="Learning the Korn Shell"><AREASHAPE="RECT"COORDS="439,0,514,21"HREF="../lrnunix/index.htm"ALT="Learning the UNIX Operating System"></MAP></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -