filearchiv.html

来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 3,680 行 · 第 1/5 页

HTML
3,680
字号
>	  </P><DIVCLASS="EXAMPLE"><HR><ANAME="WHAT"></A><P><B>例子 12-30. <BCLASS="COMMAND">浏览<TTCLASS="FILENAME">/usr/X11R6/bin</TT></B></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;  3&nbsp;# 所有在/usr/X11R6/bin中的神秘2进制文件都是些什么东西?  4&nbsp;  5&nbsp;DIRECTORY="/usr/X11R6/bin"  6&nbsp;# 也试试 "/bin", "/usr/bin", "/usr/local/bin", 等等.  7&nbsp;  8&nbsp;for file in $DIRECTORY/*  9&nbsp;do 10&nbsp;  whatis `basename $file`   # 将会echo出这个2进制文件的信息. 11&nbsp;done 12&nbsp; 13&nbsp;exit 0 14&nbsp; 15&nbsp;# 你可能希望将这个脚本的输出重定向, 像这样: 16&nbsp;# ./what.sh &#62;&#62;whatis.db 17&nbsp;# 或者一页一页的在stdout上察看, 18&nbsp;# ./what.sh | less</PRE></FONT></TD></TR></TABLE><HR></DIV><P>请参考<AHREF="loops1.html#FILEINFO">例子 10-3</A>. </P></DD><DT><BCLASS="COMMAND">vdir</B></DT><DD><P>显示详细的目录列表. 	      与<AHREF="basic.html#LSREF">ls -l</A>的效果相似. </P><P>这是一个GNU <EM>fileutils</EM>.</P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">vdir</KBD><SAMPCLASS="COMPUTEROUTPUT">total 10 -rw-r--r--    1 bozo  bozo      4034 Jul 18 22:04 data1.xrolo -rw-r--r--    1 bozo  bozo      4602 May 25 13:58 data1.xrolo.bak -rw-r--r--    1 bozo  bozo       877 Dec 17  2000 employment.xrolo</SAMP><SAMPCLASS="PROMPT">bash </SAMP><KBDCLASS="USERINPUT">ls -l</KBD><SAMPCLASS="COMPUTEROUTPUT">total 10 -rw-r--r--    1 bozo  bozo      4034 Jul 18 22:04 data1.xrolo -rw-r--r--    1 bozo  bozo      4602 May 25 13:58 data1.xrolo.bak -rw-r--r--    1 bozo  bozo       877 Dec 17  2000 employment.xrolo</SAMP>	      </PRE></FONT></TD></TR></TABLE>	      </P></DD><DT><BCLASS="COMMAND">locate</B>, <BCLASS="COMMAND">slocate</B></DT><DD><P><BCLASS="COMMAND">locate</B>命令将会在预先建立好的档案数据库中查询文件. 	      <BCLASS="COMMAND">slocate</B>命令是<BCLASS="COMMAND">locate</B>的安全版本(<BCLASS="COMMAND">locate</B>命令很有可能已经被关联到<BCLASS="COMMAND">slocate</B>命令上了). </P><P><KBDCLASS="USERINPUT">$bash locate hickson</KBD><TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="COMPUTEROUTPUT">/usr/lib/xephem/catalogs/hickson.edb</SAMP></PRE></FONT></TD></TR></TABLE></P></DD><DT><BCLASS="COMMAND">readlink</B></DT><DD><P>显示符号链接所指向的文件. </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">readlink /usr/bin/awk</KBD><SAMPCLASS="COMPUTEROUTPUT">../../bin/gawk</SAMP>	      </PRE></FONT></TD></TR></TABLE>	    </P></DD><DT><BCLASS="COMMAND">strings</B></DT><DD><P>使用<BCLASS="COMMAND">strings</B>命令在二进制或数据文件中找出可打印字符. 			  它将在目标文件中列出所有找到的可打印字符的序列. 			  这个命令对于想进行快速查找n个字符的打印检查来说是很方便的, 			  也可以用来检查一个未知格式的图片文件(<KBDCLASS="USERINPUT">strings image-file | 				  more</KBD>可能会搜索出像<SAMPCLASS="COMPUTEROUTPUT">JFIF</SAMP>这样的字符串, 			  那么这就意味着这个文件是一个<EM>jpeg</EM>格式的图片文件). 			  在脚本中, 你可能会使用<AHREF="textproc.html#GREPREF">grep</A>或者<AHREF="sedawk.html#SEDREF">sed</A>命令来分析<BCLASS="COMMAND">strings</B>命令的输出. 	      请参考<AHREF="loops1.html#BINGREP">例子 10-7</A>和<AHREF="loops1.html#FINDSTRING">例子 10-9</A>. </P><DIVCLASS="EXAMPLE"><HR><ANAME="WSTRINGS"></A><P><B>例子 12-31. 一个<SPANCLASS="QUOTE">"改进过"</SPAN>的<EM>strings</EM>命令</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# wstrings.sh: "word-strings" (增强的"strings"命令)  3&nbsp;#  4&nbsp;#  这个脚本将会通过排除标准单词列表的形式  5&nbsp;#+ 来过滤"strings"命令的输出.   6&nbsp;#  这将有效的过滤掉无意义的字符,   7&nbsp;#+ 并且只会输出可以识别的字符.   8&nbsp;  9&nbsp;# =========================================================== 10&nbsp;#                 脚本参数的标准检查 11&nbsp;ARGS=1 12&nbsp;E_BADARGS=65 13&nbsp;E_NOFILE=66 14&nbsp; 15&nbsp;if [ $# -ne $ARGS ] 16&nbsp;then 17&nbsp;  echo "Usage: `basename $0` filename" 18&nbsp;  exit $E_BADARGS 19&nbsp;fi 20&nbsp; 21&nbsp;if [ ! -f "$1" ]                      # 检查文件是否存在.  22&nbsp;then 23&nbsp;    echo "File \"$1\" does not exist." 24&nbsp;    exit $E_NOFILE 25&nbsp;fi 26&nbsp;# =========================================================== 27&nbsp; 28&nbsp; 29&nbsp;MINSTRLEN=3                           #  最小的字符串长度. 30&nbsp;WORDFILE=/usr/share/dict/linux.words  #  字典文件. 31&nbsp;                                      #  也可以指定一个不同的 32&nbsp;                                      #+ 单词列表文件, 33&nbsp;                                      #+ 但这种文件必须是以每个单词一行的方式进行保存. 34&nbsp; 35&nbsp; 36&nbsp;wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \ 37&nbsp;tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '` 38&nbsp; 39&nbsp;#  将'strings'命令的输出通过管道传递到多个'tr'命令中. 40&nbsp;#  "tr A-Z a-z" 全部转换为小写字符. 41&nbsp;#  "tr '[:space:]'" 转换空白字符为多个Z. 42&nbsp;#  "tr -cs '[:alpha:]' Z" 将非字母表字符转换为多个Z, 43&nbsp;#+ 然后去除多个连续的Z. 44&nbsp;#  "tr -s '\173-\377' Z" 把所有z后边的字符都转换为Z. 45&nbsp;#+ 并且去除多余重复的Z. (注意173(123 ascii "{")和377(255 ascii 最后一个字符)都是8进制) 46&nbsp;#+ 这样处理之后, 我们所有之前需要处理的令我们头痛的字符 47&nbsp;#+ 就全都转换为字符Z了. 48&nbsp;#  最后"tr Z ' '" 将把所有的Z都转换为空格, 49&nbsp;#+ 这样我们在下边循环中用到的变量wlist中的内容就全部以空格分隔了. 50&nbsp; 51&nbsp;#  **************************************************************** 52&nbsp;#  注意, 我们使用管道来将多个'tr'的输出传递到下一个'tr'时  53&nbsp;#+ 每次都使用了不同的参数.  54&nbsp;#  **************************************************************** 55&nbsp; 56&nbsp; 57&nbsp;for word in $wlist                    # 重要: 58&nbsp;                                      # $wlist 这里不能使用双引号. 59&nbsp;                                      # "$wlist" 不能正常工作. 60&nbsp;                                      # 为什么不行? 61&nbsp;do                                                                  62&nbsp;                                                                    63&nbsp;  strlen=${#word}                     # 字符串长度. 64&nbsp;  if [ "$strlen" -lt "$MINSTRLEN" ]   # 跳过短的字符串. 65&nbsp;  then                                                              66&nbsp;    continue                                                        67&nbsp;  fi                                                                68&nbsp;                                                                    69&nbsp;  grep -Fw $word "$WORDFILE"          #  只匹配整个单词. 70&nbsp;#      ^^^                            #  "固定字符串" 和 71&nbsp;                                      #+ "整个单词" 选项.  72&nbsp; 73&nbsp;done   74&nbsp; 75&nbsp; 76&nbsp;exit $?</PRE></FONT></TD></TR></TABLE><HR></DIV></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="COMPARISONN1"></A>Comparison</B></P><DL><DT><ANAME="DIFFREF"></A><BCLASS="COMMAND">diff</B>, <BCLASS="COMMAND">patch</B></DT><DD><P><BCLASS="COMMAND">diff</B>: 一个非常灵活的文件比较工具. 			  这个工具将会以一行接一行的形式来比较目标文件. 			  在某些应用中, 比如说比较单词词典, 			  在通过管道将结果传递给<BCLASS="COMMAND">diff</B>命令之前, 	      使用诸如<AHREF="textproc.html#SORTREF">sort</A>和<BCLASS="COMMAND">uniq</B>命令来对文件进行过滤将是非常有用的. 		  <KBDCLASS="USERINPUT">diff file-1 file-2</KBD> 		  将会输出两个文件中不同的行, 并会通过符号标识出每个不同行所属的文件. 	      </P><P><BCLASS="COMMAND">diff</B>命令的<CODECLASS="OPTION">--side-by-side</CODE>选项将会按照左右分隔的形式, 			  把两个比较中的文件全部输出, 并且会把不同的行标记出来. 	    <CODECLASS="OPTION">-c</CODE>和<CODECLASS="OPTION">-u</CODE>选项也会使得<BCLASS="COMMAND">diff</B>命令的输出变得容易解释一些. 	    </P><P>还有一些<BCLASS="COMMAND">diff</B>命令的变种, 			比如<BCLASS="COMMAND">sdiff</B>,			<BCLASS="COMMAND">wdiff</B>, <BCLASS="COMMAND">xdiff</B>, 			和<BCLASS="COMMAND">mgdiff</B>. </P><DIVCLASS="TIP"><P></P><TABLECLASS="TIP"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/tip.gif"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>如果比较的两个文件是完全一样的话, 				那么<BCLASS="COMMAND">diff</B>命令会返回0作为退出状态码, 				如果不同的话就返回1作为退出码. 	    这样<BCLASS="COMMAND">diff</B>命令就可以用在shell脚本的测试结构中了. (见下边). </P></TD></TR></TABLE></DIV><P><BCLASS="COMMAND">diff</B>命令的一个重要用法就是产生区别文件, 	这个文件将用作<BCLASS="COMMAND">patch</B>命令的<CODECLASS="OPTION">-e</CODE>选项的参数, 	      <CODECLASS="OPTION">-e</CODE>选项接受<BCLASS="COMMAND">ed</B>或<BCLASS="COMMAND">ex</B>脚本. 	      </P><P><BCLASS="COMMAND">patch</B>: 灵活的版本工具. 			  给出一个用<BCLASS="COMMAND">diff</B>命令产生的区别文件, 			  <BCLASS="COMMAND">patch</B>命令可以将一个老版本的包更新为一个新版本的包. 			  因为你发布一个小的<SPANCLASS="QUOTE">"区别"</SPAN>文件远比重新发布一个大的软件包来的容易得多. 	      对于频繁更新的Linux内核来说, 使用内核<SPANCLASS="QUOTE">"补丁包"</SPAN>的形式来发布是一种非常好的办法. 	      </P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;patch -p1 &#60;patch-file  2&nbsp;# 在'patch-file'中取得所有的修改列表,   3&nbsp;# 然后把它们更新到相应的文件中.   4&nbsp;# 那么这个包就被更新为新版本了. </PRE></FONT></TD></TR></TABLE></P><P>更新内核: </P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;cd /usr/src  2&nbsp;gzip -cd patchXX.gz | patch -p0  3&nbsp;# 使用'patch'来更新内核源文件.  4&nbsp;# 来自于linux内核文档"README",  5&nbsp;# 这份文档由匿名作者(Alan Cox?)所编写. </PRE></FONT></TD></TR></TABLE></P><DIVCLASS="NOTE"><P></P><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/note.gif"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P><BCLASS="COMMAND">diff</B>也可以递归的比较目录下的所有文件(包含子目录). </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">diff -r ~/notes1 ~/notes2</KBD><SAMPCLASS="COMPUTEROUTPUT">Only in /home/bozo/notes1: file02 Only in /home/bozo/notes1: file03 Only in /home/bozo/notes2: file04</SAMP>	      </PRE></FONT></TD></TR></TABLE>	    </P></TD></TR></TABLE></DIV><DIVCLASS="TIP"><P></P><TABLECLASS="TIP"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/tip.gif"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>使用<BCLASS="COMMAND">zdiff</B>来比较<EM>gzip</EM>文件. </P></TD></TR></TABLE></DIV></DD><DT><BCLASS="COMMAND">diff3</B></DT><DD><P>这是<BCLASS="COMMAND">diff</B>命令的扩展版本, 			可以同时比较三个文件. 			如果成功执行那么这个命令就返回0, 			但不幸的是这个命令不给出比较结果的信息. 	      </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">diff3 file-1 file-2 file-3</KBD><SAMPCLASS="COMPUTEROUTPUT">==== 1:1c   This is line 1 of "file-1". 2:1c   This is line 1 of "file-2". 3:1c   This is line 1 of "file-3"</SAMP>	      </PRE></FONT></TD></TR></TABLE>	      </P></DD><DT><BCLASS="COMMAND">sdiff</B></DT><DD><P>比较和(或)编辑两个文件, 			  将它们合并到一个输出文件中. 			  由于这个命令的交互特性, 			  所以在脚本中很少使用这个命令.	      </P></DD><DT><BCLASS="COMMAND">cmp</B></DT><DD><P><BCLASS="COMMAND">cmp</B

⌨️ 快捷键说明

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