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

📄 341.html

📁 著名的linux英雄站点的文档打包
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<br>
In the Bourne shell, you can open or dup arbitrary file descriptors.<br>
For example,<br>
<br>
   exec 2&gt;errs.out<br>
<br>
means that from then on, stderr goes into errs file.<br>
<br>
Or what if you just want to throw away stderr and leave stdout<br>
alone?    Pretty simple operation, eh?<br>
<br>
   cmd 2&gt;/dev/null<br>
<br>
Works in the Bourne shell.  In the csh, you can only make a pitiful<br>
attempt like this:<br>
<br>
   (cmd &gt; /dev/tty) &gt;& /dev/null<br>
<br>
But who said that stdout was my tty?  So it's wrong.  This simple<br>
operation *CANNOT BE DONE* in the csh.<br>
<br>
<br>
Along these same lines, you can't direct error messages in csh scripts<br>
out stderr as is considered proper.  In the Bourne shell, you might say:<br>
<br>
echo "$0: cannot find $file" 1&gt;&2<br>
<br>
but in the csh, you can't redirect stdout out stderr, so you end<br>
up doing something silly like this:<br>
<br>
sh -c 'echo "$0: cannot find $file" 1&gt;&2'<br>
<br>
1b. Reading Files<br>
<br>
In the csh, all you've got is $&lt;, which reads a line from your tty.  What<br>
if you've redirected stdin?  Tough noogies, you still get your tty, which<br>
you really can't redirect.  Now, the read statement<br>
in the Bourne shell allows you to read from stdin, which catches<br>
redirection.  It also means that you can do things like this:<br>
<br>
   exec 3&lt;file1<br>
   exec 4&lt;file2<br>
<br>
Now you can read from fd 3 and get lines from file1, or from file2 through<br>
fd 4.   In modern, Bourne-like shells, this suffices:<br>
<br>
   read some_var 0&lt;&3<br>
   read another_var 0&lt;&4<br>
<br>
Although in older ones where read only goes from 0, you trick it:<br>
<br>
   exec 5&lt;&0  # save old stdin<br>
   exec 0&lt;&3; read some_var<br>
   exec 0&lt;&4; read another_var<br>
   exec 0&lt;&5  # restore it<br>
<br>
<br>
1c. Closing FDs<br>
<br>
In the Bourne shell, you can close file descriptors you don't<br>
want open, like 2&gt;&-, which isn't the same as redirecting it<br>
to /dev/null.<br>
<br>
1d. More Elaborate Combinations<br>
<br>
Maybe you want to pipe stderr to a command and leave stdout alone.<br>
Not too hard an idea, right?  You can't do this in the csh as I<br>
mentioned in 1a.  In a Bourne shell, you can do things like this:<br>
<br>
   exec 3&gt;&1; grep yyy xxx 2&gt;&1 1&gt;&3 3&gt;&- | sed s/file/foobar/ 1&gt;&2 3&gt;&-<br>
   grep: xxx: No such foobar or directory<br>
<br>
Normal output would be unaffected.  The closes there were in case<br>
something really cared about all its FDs.  We send stderr to sed,<br>
and then put it back out 2.<br>
<br>
Consider the pipeline:<br>
<br>
   A | B | C<br>
<br>
You want to know the status of C, well, that's easy: it's in $?, or<br>
$status in csh.  But if you want it from A, you're out of luck -- if<br>
you're in the csh, that is.  In the Bourne shell, you can get it, although<br>
doing so is a bit tricky.  Here's something I had to do where I ran dd's<br>
stderr into a grep -v pipe to get rid of the records in/out noise, but had<br>
to return the dd's exit status, not the grep's:<br>
<br>
   device=/dev/rmt8<br>
   dd_noise='^[0-9]++[0-9]+ records (in|out)$'<br>
   exec 3&gt;&1<br>
   status=`((dd if=$device ibs=64k 2&gt;&1 1&gt;&3 3&gt;&- 4&gt;&-; echo $? &gt;&4) |<br>
egrep -v "$dd_noise" 1&gt;&2 3&gt;&- 4&gt;&-) 4&gt;&1`<br>
   exit $status;<br>
<br>
<br>
The csh has also been known to close all open file descriptors besides<br>
the ones it knows about, making it unsuitable for applications that<br>
intend to inherit open file descriptors.<br>
<br>
<br>
2. COMMAND ORTHOGONALITY<br>
<br>
2a. Built-ins<br>
<br>
The csh is a horrid botch with its built-ins.  You can't put them<br>
together in many reasonable ways.   Even simple little things like this:<br>
<br>
   % time | echo<br>
<br>
which while nonsensical, shouldn't give me this message:<br>
<br>
   Reset tty pgrp from 9341 to 26678<br>
<br>
Others are more fun:<br>
<br>
   % sleep 1 | while<br>
   while: Too few arguments.<br>
   [5] 9402<br>
   % jobs<br>
   [5]     9402 Done                 sleep |<br>
<br>
<br>
Some can even hang your shell.  Try typing ^Z while you're sourcing<br>
something, or redirecting a source command.  Just make sure you have<br>
another window handy.  Or try<br>
<br>
   % history | more<br>
<br>
on some systems.<br>
<br>
Aliases are not evaluated everywhere you would like them do be:<br>
<br>
   % alias lu 'ls -u'<br>
   % lu<br>
   HISTORY  News     bin      fortran  lib      lyrics   misc     tex<br>
   Mail     TEX      dehnung  hpview   logs     mbox     netlib<br>
   % repeat 3 lu<br>
   lu: Command not found.<br>
   lu: Command not found.<br>
   lu: Command not found.<br>
<br>
   % time lu<br>
   lu: Command not found.<br>
<br>
<br>
2b. Flow control<br>
<br>
You can't mix flow-control and commands, like this:<br>
   <br>
   who | while read line; do<br>
echo "gotta $line"<br>
   done<br>
<br>
<br>
You can't combine multiline constructs in a csh using semicolons.<br>
There's no easy way to do this<br>
<br>
   alias cmd 'if (foo) then bar; else snark; endif'<br>
<br>
<br>
You can't perform redirections with if statements that are<br>
evaluated solely for their exit status:<br>
<br>
   if ( { grep vt100 /etc/termcap &gt; /dev/null } ) echo ok<br>
<br>
And even pipes don't work:<br>
<br>
   if ( { grep vt100 /etc/termcap | sed 's/$/###' } ) echo ok<br>
<br>
But these work just fine in the Bourne shell:<br>
<br>
   if grep vt100 /etc/termcap &gt; /dev/null ; then echo ok; fi  <br>
<br>
   if grep vt100 /etc/termcap | sed 's/$/###/' ; then echo ok; fi<br>
<br>
<br>
Consider the following reasonable construct:<br>
<br>
 if ( { command1 | command2 } ) then<br>
     ...<br>
 endif<br>
<br>
The output of command1 won't go into the input of command2.  You will get<br>
the output of both commands on standard output.  No error is raised.  In<br>
the Bourne shell or its clones, you would say<br>
<br>
   if command1 | command2 ; then<br>
...<br>
   fi<br>
<br>
<br>
2c. Stupid parsing bugs<br>
<br>
Certain reasonable things just don't work, like this:<br>
<br>
   % kill -1 `cat foo`<br>
   `cat foo`: Ambiguous.<br>
<br>
But this is ok:<br>
<br>
   % /bin/kill -1 `cat foo`<br>
<br>
If you have a stopped job:<br>
<br>
   [2]     Stopped              rlogin globhost<br>
<br>
You should be able to kill it with<br>
<br>
   % kill %?glob<br>
   kill: No match<br>
<br>
but<br>
<br>
   % fg %?glob<br>
<br>
works.<br>
<br>
White space can matter:<br>
<br>
   if(expr)<br>
<br>
may fail on some versions of csh, while<br>
<br>
   if (expr)<br>
<br>
works!  Your vendor may have attempted to fix this bug, but odds are good<br>
that their csh still won't be able to handle<br>
<br>
   if(0) then<br>
     if(1) then<br>
         echo A: got here<br>
     else<br>
         echo B: got here<br>
     endif<br>
     echo We should never execute this statement<br>
   endif<br>
<br>
3. SIGNALS<br>
<br>
In the csh, all you can do with signals is trap SIGINT.  In the Bourne<br>
shell, you can trap any signal, or the end-of-program exit.    For example,<br>
to blow away a tempfile on any of a variety of signals:<br>
<br>
   $ trap 'rm -f /usr/adm/tmp/i$$ ;<br>
   echo "ERROR: abnormal exit";<br>
   exit' 1 2 3 15<br>
<br>
   $ trap 'rm tmp.$$' 0   # on program exit<br>
<br>
4. QUOTING<br>
<br>
You can't quote things reasonably in the csh:<br>
<br>
   set foo = "Bill asked, "How's tricks?""<br>
<br>
doesn't work.  This makes it really hard to construct strings with<br>
mixed quotes in them.  In the Bourne shell, this works just fine.<br>
In fact, so does this:<br>
<br>
    cd /mnt; /usr/ucb/finger -m -s `ls `u``<br>
<br>
Dollar signs cannot be escaped in double quotes in the csh.  Ug.<br>
<br>
   set foo = "this is a $dollar quoted and this is $HOME not quoted"<br>
   dollar: Undefined variable.<br>
<br>
You have to use backslashes for newlines, and it's just darn hard to<br>
get them into strings sometimes.<br>
<br>
   set foo = "this <br>
   and that";<br>
   echo $foo<br>
   this  and that<br>
   echo "$foo"<br>
   Unmatched ".  <br>
<br>
Say what?  You don't have these problems in the Bourne shell, where it's<br>
just fine to write things like this:<br>
<br>
   echo 'This is<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -