⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch47_02.htm

📁 the unix power tools
💻 HTM
📖 第 1 页 / 共 2 页
字号:
><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>kill %?glob</B></CODE>kill: No match</PRE></BLOCKQUOTE></P><PCLASS="para">but:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>fg %?glob</B></CODE></PRE></BLOCKQUOTE></P><PCLASS="para">works.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56366"></A><ACLASS="indexterm"NAME="AUTOID-56369"></A>White space can matter:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">if(expr)</PRE></BLOCKQUOTE></P><PCLASS="para">may fail on some versions of csh, while:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">if (expr)</PRE></BLOCKQUOTE></P><PCLASS="para">works!</P></DIV></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-393-SECT-1.3">47.2.3 Signals </A></H3><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56381"></A><ACLASS="indexterm"NAME="AUTOID-56383"></A><ACLASS="indexterm"NAME="AUTOID-56386"></A><ACLASS="indexterm"NAME="AUTOID-56389"></A><ACLASS="indexterm"NAME="AUTOID-56392"></A>In the C shell, all you can do with signals is trap <EMCLASS="emphasis">SIGINT</EM>.In the Bourne shell, you can trap any signal, or the end-of-program exit.For example, to blow away a temporary file on any of a variety of signals:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">trap 'rm -f /usr/adm/tmp/i$$ ;    echo &quot;ERROR: abnormal exit&quot;;    exit' 1 2 3 15trap 'rm tmp.$$' 0   # on program exit</PRE></BLOCKQUOTE></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-393-SECT-1.4">47.2.4 Quoting </A></H3><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56401"></A><ACLASS="indexterm"NAME="AUTOID-56404"></A><ACLASS="indexterm"NAME="AUTOID-56407"></A><ACLASS="indexterm"NAME="AUTOID-56410"></A>You can't quote things reasonably in the <EMCLASS="emphasis">csh</EM>:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">set foo = &quot;Bill asked, \&quot;How's tricks?\&quot;&quot;</PRE></BLOCKQUOTE></P><PCLASS="para">doesn't work.This makes it<SPANCLASS="link">really hard (<ACLASS="linkend"HREF="ch10_08.htm"TITLE="Fix Quoting in csh Aliases with makealias and quote ">10.8</A>)</SPAN>to construct strings with mixed quotes in them.In the Bourne shell, this works just fine. In fact, so does this:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">cd /mnt; /usr/ucb/finger -m -s `ls \`u\``</PRE></BLOCKQUOTE></P><PCLASS="para">Dollar signs (<CODECLASS="literal">$</CODE>) cannot be escaped in double quotes in the<EMCLASS="emphasis">csh</EM>.Ugh.</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">set foo = &quot;this is a \$dollar quoted and this is $HOME not quoted&quot; dollar: Undefined variable.</PRE></BLOCKQUOTE></P><PCLASS="para">You have to use backslashes (<CODECLASS="literal">\</CODE>) for newlines, and it's just darnhard toget them into strings sometimes.</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen"><ACLASS="indexterm"NAME="AUTOID-56429"></A>% <CODECLASS="userinput"><B>set foo = &quot;this \and that&quot;;</B></CODE>% <CODECLASS="userinput"><B>echo $foo</B></CODE>this  and that% <CODECLASS="userinput"><B>echo &quot;$foo&quot;</B></CODE>Unmatched &quot;.</PRE></BLOCKQUOTE></P><PCLASS="para">Say what?You don't have these problems in the Bourne shell, where it'sjust fine to write things like this:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">echo    'This is      some text that contains     several newlines.'</PRE></BLOCKQUOTE></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-393-SECT-1.5">47.2.5 Variable Syntax </A></H3><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56441"></A><ACLASS="indexterm"NAME="AUTOID-56444"></A><ACLASS="indexterm"NAME="AUTOID-56447"></A><ACLASS="indexterm"NAME="AUTOID-56450"></A><ACLASS="indexterm"NAME="AUTOID-56453"></A><ACLASS="indexterm"NAME="AUTOID-56456"></A><ACLASS="indexterm"NAME="AUTOID-56459"></A><ACLASS="indexterm"NAME="AUTOID-56462"></A>There's this big difference between global -vironment) and local(shell) variables.In <EMCLASS="emphasis">csh</EM>, you use a totally different syntax to set one from the other.</P><PCLASS="para">In Bourne shell, this: </P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">VAR=foo cmds args</PRE></BLOCKQUOTE></P><PCLASS="para">is the same as:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">(export VAR; VAR=foo; cmd args)</PRE></BLOCKQUOTE></P><PCLASS="para">or <EMCLASS="emphasis">csh</EM>'s:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">(setenv VAR; cmd args)</PRE></BLOCKQUOTE></P><PCLASS="para">You can't use<SPANCLASS="link"><CODECLASS="literal">:t</CODE>, <CODECLASS="literal">:h</CODE>, etc. (<ACLASS="linkend"HREF="ch09_06.htm"TITLE="String Editing (Colon) Operators ">9.6</A>)</SPAN>on environment variables.Watch:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>echo Try testing with $SHELL:t</B></CODE>Try testing with /bin/csh:t</PRE></BLOCKQUOTE></P><PCLASS="para">It's really nice to be able to say<SPANCLASS="link"><CODECLASS="literal">${PAGER-more}</CODE> or <CODECLASS="literal">FOO=${BAR:-${BAZ}}</CODE> (<ACLASS="linkend"HREF="ch45_12.htm"TITLE="Parameter Substitution ">45.12</A>)</SPAN>to be able to run the user's <EMCLASS="emphasis">PAGER</EM> if set, and <EMCLASS="emphasis">more</EM> otherwise.You can't do this in the <EMCLASS="emphasis">csh</EM>.It takes more verbiage.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56491"></A>You can't get the process number of the last background command from theC shell, something you might like to do if you're starting up several jobs inthe background.In the Bourne shell, the PID of the last command put inthe background is available in <CODECLASS="userinput"><B>$!</B></CODE>.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56496"></A><ACLASS="indexterm"NAME="AUTOID-56499"></A><ACLASS="indexterm"NAME="AUTOID-56502"></A><ACLASS="indexterm"NAME="AUTOID-56505"></A>The <EMCLASS="emphasis">csh</EM> is also flaky about what it does when it imports an environment variable into a local shell variable, as it doeswith <EMCLASS="emphasis">HOME</EM>, <EMCLASS="emphasis">USER</EM>, <EMCLASS="emphasis">PATH</EM>, and <EMCLASS="emphasis">TERM</EM>.Consider this:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>setenv TERM '`/bin/ls -l / &gt; /dev/tty`'</B></CODE>% <CODECLASS="userinput"><B>csh -f</B></CODE></PRE></BLOCKQUOTE></P><PCLASS="para">And watch the fun!</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-393-SECT-1.6">47.2.6 Expression Evaluation </A></H3><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56521"></A><ACLASS="indexterm"NAME="AUTOID-56524"></A>Consider this statement in the <EMCLASS="emphasis">csh</EM>:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">if ($?MANPAGER) setenv PAGER $MANPAGER</PRE></BLOCKQUOTE></P><PCLASS="para">Despite your attempts to set only <EMCLASS="emphasis">PAGER</EM> when you wantto, the <EMCLASS="emphasis">csh</EM> aborts:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">MANPAGER: Undefined variable.</PRE></BLOCKQUOTE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56536"></A>That's because it parses the whole line anyway <EMCLASS="emphasis">and evaluates it</EM>!You have to write this:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">if ($?MANPAGER) then    setenv PAGER $MANPAGERendif</PRE></BLOCKQUOTE></P><PCLASS="para">That's the same problem you have here:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>if ($?X &amp;&amp; $X == 'foo') echo ok</B></CODE>X: Undefined variable</PRE></BLOCKQUOTE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56547"></A>This forces you to write a couple of nested <EMCLASS="emphasis">if</EM> statements.This is highly undesirable because it renders short-circuit Booleans useless in situations like these.If the <EMCLASS="emphasis">csh</EM> were really C-like, you would expect to be ableto safely employ this kind of logic.Consider the common C construct:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">if (p &amp;&amp; p-&gt;member)</PRE></BLOCKQUOTE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56555"></A>Undefined variables are not fatal errors in the Bourne shell, so this issue does not arise there.</P><PCLASS="para">While the <EMCLASS="emphasis">csh</EM> does have built-in expression handling, it's notwhat you might think.In fact, it's space-sensitive.This is an error:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">@ a = 4/2</PRE></BLOCKQUOTE></P><PCLASS="para">but this is okay:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">@ a = 4 / 2</PRE></BLOCKQUOTE></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-393-SECT-1.7">47.2.7 Error Handling </A></H3><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-56568"></A><ACLASS="indexterm"NAME="AUTOID-56571"></A>Wouldn't it be nice to know you had an error in your script beforeyou ran it?That's what the <EMCLASS="emphasis">-n</EM> flag is for: just check the syntax.This is especially good to make sure seldom taken segments of code are correct.Alas, the <EMCLASS="emphasis">csh</EM> implementation of this doesn't work.Consider this statement:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">exit (i)</PRE></BLOCKQUOTE></P><PCLASS="para">Of course, they really meant:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">exit (1)</PRE></BLOCKQUOTE></P><PCLASS="para">or just:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">exit 1</PRE></BLOCKQUOTE></P><PCLASS="para">Either shell will complain about this.But if you hide this in an <EMCLASS="emphasis">if</EM> clause, like so:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">#!/bin/csh -fnif (1) then    exit (i)endif</PRE></BLOCKQUOTE></P><PCLASS="para">the C shell tells you there's nothing wrong with this script.The equivalentconstruct in the Bourne shell, on the other hand, tells you this:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">#!/bin/sh -nif (1) then    exit (i)endif/tmp/x: syntax error at line 3: `(' unexpected</PRE></BLOCKQUOTE></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-393-SECT-1.8">47.2.8 Random Bugs </A></H3><PCLASS="para">Here's one:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">!%s%x%s</PRE></BLOCKQUOTE></P><PCLASS="para">Core dump, or garbage.</P><PCLASS="para">If you have an alias with backquotes (<CODECLASS="literal">``</CODE>), and use that in backquotes in another one, you get a core dump.</P><PCLASS="para">Try this:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>repeat 3 echo &quot;/vmu*&quot;</B></CODE>/vmu*/vmunix/vmunix</PRE></BLOCKQUOTE></P><PCLASS="para">What???</P><PCLASS="para">While some vendors have fixed some of the <EMCLASS="emphasis">csh</EM>'s bugs (the<SPANCLASS="link"><EMCLASS="emphasis">tcsh</EM> (<ACLASS="linkend"HREF="ch08_03.htm"TITLE="Introduction to tcsh">8.3</A>)</SPAN>alsodoes much better here), most of its problems can never be solvedbecause they're a result of braindead design decisions.Do yourselfa favor, and if you have to write a shell script, do it in the Bourne shell.<ACLASS="indexterm"NAME="AUTOID-56608"></A><ACLASS="indexterm"NAME="AUTOID-56609"></A><ACLASS="indexterm"NAME="AUTOID-56610"></A><ACLASS="indexterm"NAME="AUTOID-56611"></A><ACLASS="indexterm"NAME="AUTOID-56612"></A></P></DIV><DIVCLASS="sect1info"><PCLASS="SECT1INFO">- <SPANCLASS="authorinitials">TC</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="ch47_01.htm"TITLE="47.1 Why Not? "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 47.1 Why Not? "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="ch47_03.htm"TITLE="47.3 Conditional Statements with if "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 47.3 Conditional Statements with if "BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">47.1 Why Not? </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">47.3 Conditional Statements with if </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 &amp; 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 + -