📄 ch44_18.htm
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 44] 44.18 Standard Command-Line Parsing </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:53:57Z"><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="ch44_01.htm"TITLE="44. Shell Programming for the Uninitiated"><LINKREL="prev"HREF="ch44_17.htm"TITLE="44.17 Handling Arguments with while and shift "><LINKREL="next"HREF="ch44_19.htm"TITLE="44.19 The Bourne Shell set Command "></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="ch44_17.htm"TITLE="44.17 Handling Arguments with while and shift "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 44.17 Handling Arguments with while and shift "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1">Chapter 44<BR>Shell Programming for the Uninitiated</FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch44_19.htm"TITLE="44.19 The Bourne Shell set Command "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 44.19 The Bourne Shell set Command "BORDER="0"></A></TD></TR></TABLE> <HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-8009">44.18 Standard Command-Line Parsing </A></H2><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-51642"></A><ACLASS="indexterm"NAME="AUTOID-51645"></A>Most shell scripts need to handle command-line arguments - options, filenames,and so on.Articles<ACLASS="xref"HREF="ch44_15.htm"TITLE="Handling Command-Line Arguments in Shell Scripts ">44.15</A>,<ACLASS="xref"HREF="ch44_16.htm"TITLE="Handling Command-Line Arguments with a for Loop ">44.16</A>,and<ACLASS="xref"HREF="ch44_17.htm"TITLE="Handling Arguments with while and shift ">44.17</A>show how to parse command lines with any Bourne shell.Those methods have two problems.You can't combine arguments with a single dash, e.g., <CODECLASS="literal">-abc</CODE> instead of <CODECLASS="literal">-a -b -c</CODE>.You also can't specify arguments to optionswithout a space in between, e.g., <CODECLASS="literal">-b</CODE><CODECLASS="replaceable"><I>arg</I></CODE> in addition to<CODECLASS="literal">-b </CODE><CODECLASS="replaceable"><I>arg</I></CODE>.[6]</P><BLOCKQUOTECLASS="footnote"><PCLASS="para">[6] Although most UNIX commands allow this, it is actually contrary to theCommand Syntax Standard Rules in <EMCLASS="emphasis">intro</EM> of the User's Manual.The version of <EMCLASS="emphasis">getopt</EM> on the CD-ROM supports this syntax.The <EMCLASS="emphasis">getopts</EM> we've seen also support this, but may not in future releases.</P></BLOCKQUOTE><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-51663"></A>Your Bourne shell may have a built-in command named <EMCLASS="emphasis">getopts</EM>.constraints.[7]<EMCLASS="emphasis">getopts</EM> lets you deal with multiple complex options without theseTo find out whether your shell has <EMCLASS="emphasis">getopts</EM>,see your on-line <EMCLASS="emphasis">sh</EM> or <EMCLASS="emphasis">getopts</EM>(1) manual page.</P><BLOCKQUOTECLASS="footnote"><PCLASS="para">[7] Both <EMCLASS="emphasis">bash</EM> and <EMCLASS="emphasis">ksh</EM> have it.<EMCLASS="emphasis">getopts</EM> replaces the old command <EMCLASS="emphasis">getopt</EM>; itis better integrated into the shell's syntax and runs moreefficiently.C programmers will recognize <EMCLASS="emphasis">getopts</EM> as very similarto the standard library routine <EMCLASS="emphasis">getopt</EM>(3).</P></BLOCKQUOTE><TABLECLASS="para.programreference"BORDER="1"><TR><THVALIGN="TOP"><ACLASS="programreference"HREF="examples/index.htm"TITLE="getopt">getopt</A><BR></TH><TDVALIGN="TOP">If your shell doesn't have <EMCLASS="emphasis">getopts</EM>, you can use the command named<EMCLASS="emphasis">getopt</EM> on the CD-ROM.<EMCLASS="emphasis">getopts</EM> works differently from <EMCLASS="emphasis">getopt</EM>; we won't cover it here.</TD></TR></TABLE><PCLASS="para"><EMCLASS="emphasis">getopt</EM> takes two or more arguments.<ACLASS="indexterm"NAME="AUTOID-51685"></A><ACLASS="indexterm"NAME="AUTOID-51687"></A><ACLASS="indexterm"NAME="AUTOID-51690"></A>The firstis a string that can contain lettersand colons (<CODECLASS="literal">:</CODE>).Each letter names a valid option; if a letter is followedby a colon, the option requires an argument.The second and following arguments are the original command-lineoptions; you'll usually give<SPANCLASS="link"><CODECLASS="literal">"$@"</CODE> (<ACLASS="linkend"HREF="ch44_15.htm"TITLE="Handling Command-Line Arguments in Shell Scripts ">44.15</A>)</SPAN>to pass all the arguments to <EMCLASS="emphasis">getopt</EM>.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-51699"></A><ACLASS="indexterm"NAME="AUTOID-51702"></A><EMCLASS="emphasis">getopt</EM> picks eachoption off the command line, checks to see if the option is valid,and writes the correct option to its standard output.If an option has an argument, <EMCLASS="emphasis">getopt</EM> writes the argument after itsoption.When <EMCLASS="emphasis">getopt</EM> finds the first non-option argument (the firstargument that doesn't start with a <CODECLASS="literal">-</CODE> character), it outputstwo dashes (<CODECLASS="literal">-</CODE>) and the rest of the arguments.If <EMCLASS="emphasis">getopt</EM> finds an invalid option, or an option that should havean argument but doesn't, it prints an error message and returns a non-zero<SPANCLASS="link">status (<ACLASS="linkend"HREF="ch44_07.htm"TITLE="Exit Status of UNIX Processes ">44.7</A>)</SPAN>.</P><PCLASS="para">Your script can use a loop to parse the <EMCLASS="emphasis">getopt</EM> output.Here's an example script named <EMCLASS="emphasis">opttest</EM> that shows how<EMCLASS="emphasis">getopt</EM> works.</P><PCLASS="para"><TABLECLASS="screen.co"BORDER="1"><TR><THVALIGN="TOP"><PRECLASS="calloutlist"> <ACLASS="co"HREF="ch44_09.htm"TITLE="44.9 Testing Your Success ">||</A> <ACLASS="co"HREF="ch13_08.htm"TITLE="13.8 Using {list} to Group Bourne Shell Commands ">{</A> <ACLASS="co"HREF="ch45_09.htm"TITLE='45.9 The Unappreciated Bourne Shell ":" Operator'>:</A> </PRE></TH><TDVALIGN="TOP"><PRECLASS="screen"><ACLASS="indexterm"NAME="AUTOID-51719"></A><ACLASS="indexterm"NAME="AUTOID-51722"></A><ACLASS="indexterm"NAME="AUTOID-51724"></A><ACLASS="indexterm"NAME="AUTOID-51727"></A><ACLASS="indexterm"NAME="AUTOID-51730"></A>#!/bin/shset -- `getopt "ab:" "$@"` || { echo "Usage: `basename $0` [-a] [-b name] [files]" 1>&2 exit 1}echo "Before loop, command line has: $*"aflag=0 name=NONEwhile :do case "$1" in -a) aflag=1 ;; -b) shift; name="$1" ;; --) break ;; esac shiftdoneshift # REMOVE THE TRAILING --echo "aflag=$aflag / name=$name / Files are $*"</PRE></TD></TR></TABLE></P><PCLASS="para">The script has two legal options.The <EMCLASS="emphasis">-a</EM> option sets the variable named <EMCLASS="emphasis">aflag</EM> to <CODECLASS="literal">1</CODE>.The <EMCLASS="emphasis">-b</EM> option takes a single argument; the argument is storedin the variable named <EMCLASS="emphasis">name</EM>.Any other arguments are filenames.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-51743"></A><ACLASS="indexterm"NAME="AUTOID-51746"></A><ACLASS="indexterm"NAME="AUTOID-51749"></A>The script starts by running <EMCLASS="emphasis">getopt</EM> inside<SPANCLASS="link">backquotes (<ACLASS="linkend"HREF="ch09_16.htm"TITLE="Command Substitution ">9.16</A>)</SPAN>-and using the<SPANCLASS="link"><EMCLASS="emphasis">set</EM> (<ACLASS="linkend"HREF="ch44_19.htm"TITLE="The Bourne Shell set Command ">44.19</A>)</SPAN>command to replace the command-line arguments with the <EMCLASS="emphasis">getopt</EM> output.The first argument to <EMCLASS="emphasis">set</EM>,<SPANCLASS="link"><CODECLASS="literal">-</CODE> (two dashes) (<ACLASS="linkend"HREF="ch44_19.htm"TITLE="The Bourne Shell set Command ">44.19</A>)</SPAN>,is important:it makes sure that <EMCLASS="emphasis">set</EM> passes the script's options to <EMCLASS="emphasis">getopt</EM>instead of treating them as options to the shell itself.An <EMCLASS="emphasis">echo</EM> command shows the output of <EMCLASS="emphasis">getopt</EM>.Then the loop parses the <EMCLASS="emphasis">getopt</EM> output, setting shell variablesas it goes.When the loop finds the <CODECLASS="literal">-</CODE> argument from <EMCLASS="emphasis">getopt</EM>, it quits andleaves the remaining filenames (if any) in the command-line arguments.A second <EMCLASS="emphasis">echo</EM> shows what's in the shell variables and on thecommand line after the loop.Here are a few examples:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>opttest</B></CODE>Before loop, command line has: -- aflag=0 / name=NONE / Files are % <CODECLASS="userinput"><B>opttest -b file1 -a file2 file3</B></CODE>Before loop, command line has: -b file1 -a -- file2 file3aflag=1 / name=file1 / Files are file2 file3% <CODECLASS="userinput"><B>opttest -q -b file1</B></CODE>getopt: illegal option -- qUsage: opttest [-a] [-b name] [files]% <CODECLASS="userinput"><B>opttest -bfile1</B></CODE>Before loop, command line has: -b file1 --aflag=0 / name=file1 / Files are % <CODECLASS="userinput"><B>opttest -ab</B></CODE>getopt: option requires an argument -- bUsage: opttest [-a] [-b name] [files]</PRE></BLOCKQUOTE></P><PCLASS="para">The advantages of <EMCLASS="emphasis">getopt</EM> are that it minimizes extra codenecessary to process options and fully supports the standard UNIX optionsyntax (as specified in <EMCLASS="emphasis">intro</EM> of the User's Manual).</P><DIVCLASS="sect1info"><PCLASS="SECT1INFO">- <SPANCLASS="authorinitials">JP</SPAN>, <SPANCLASS="authorinitials">BR</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="ch44_17.htm"TITLE="44.17 Handling Arguments with while and shift "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 44.17 Handling Arguments with while and shift "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="ch44_19.htm"TITLE="44.19 The Bourne Shell set Command "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 44.19 The Bourne Shell set Command "BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">44.17 Handling Arguments with while and shift </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">44.19 The Bourne Shell set Command </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 + -