filearchiv.html

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

HTML
3,680
字号
>命令是上边<BCLASS="COMMAND">diff</B>命令的一个简单版本. 			  <BCLASS="COMMAND">diff</B>命令会报告两个文件的不同之处, 			  而<BCLASS="COMMAND">cmp</B>命令仅仅指出哪些位置有所不同, 	      不会显示不同之处的具体细节. </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>命令那样, 			  如果两个文件相同的话, 			  <BCLASS="COMMAND">cmp</B>将返回0作为退出状态码, 			  如果不同就返回1. 这样能用在shell脚本的测试结构中了. </P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="FILECOMP"></A><P><B>例子 12-32. 在一个脚本中使用<BCLASS="COMMAND">cmp</B>命令来比较两个文件. </B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;  3&nbsp;ARGS=2  # 脚本需要两个参数.   4&nbsp;E_BADARGS=65  5&nbsp;E_UNREADABLE=66  6&nbsp;  7&nbsp;if [ $# -ne "$ARGS" ]  8&nbsp;then  9&nbsp;  echo "Usage: `basename $0` file1 file2" 10&nbsp;  exit $E_BADARGS 11&nbsp;fi 12&nbsp; 13&nbsp;if [[ ! -r "$1" || ! -r "$2" ]] 14&nbsp;then 15&nbsp;  echo "Both files to be compared must exist and be readable." 16&nbsp;  exit $E_UNREADABLE 17&nbsp;fi 18&nbsp; 19&nbsp;cmp $1 $2 &#38;&#62; /dev/null  # /dev/null将会禁止"cmp"命令的输出. 20&nbsp;#   cmp -s $1 $2 与上边这句的结果相同("-s"选项是禁止输出(silent)标志) 21&nbsp;#   感谢Anders Gustavsson指出这点. 22&nbsp;# 23&nbsp;# 使用'diff'命令也可以, 比如,   diff $1 $2 &#38;&#62; /dev/null 24&nbsp; 25&nbsp;if [ $? -eq 0 ]         # 测试"cmp"命令的退出状态. 26&nbsp;then 27&nbsp;  echo "File \"$1\" is identical to file \"$2\"." 28&nbsp;else   29&nbsp;  echo "File \"$1\" differs from file \"$2\"." 30&nbsp;fi 31&nbsp; 32&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></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">zcmp</B>处理<EM>gzip</EM>文件. </P></TD></TR></TABLE></DIV></DD><DT><BCLASS="COMMAND">comm</B></DT><DD><P>多功能的文件比较工具. 使用这个命令之前必须先排序. 	      </P><P><BCLASS="COMMAND">comm		<TTCLASS="REPLACEABLE"><I>-options</I></TT>		<TTCLASS="REPLACEABLE"><I>first-file</I></TT>		<TTCLASS="REPLACEABLE"><I>second-file</I></TT></B></P><P><KBDCLASS="USERINPUT">comm file-1 file-2</KBD> 将会输出3列: 	      <P></P><UL><LI><P>第1列 = 只在<TTCLASS="FILENAME">file-1</TT>中存在的行</P></LI><LI><P>第2列 = 只在<TTCLASS="FILENAME">file-2</TT>中存在的行</P></LI><LI><P>第3列 = 两边相同的行. </P></LI></UL></P><P>下列选项可以禁止一列或多列的输出.	      <P></P><UL><LI><P><CODECLASS="OPTION">-1</CODE> 禁止显示第<TTCLASS="LITERAL">1</TT>列 (译者: 在File1中的行)</P></LI><LI><P><CODECLASS="OPTION">-2</CODE> 禁止显示第<TTCLASS="LITERAL">2</TT>列 (译者: 在File2中的行)</P></LI><LI><P><CODECLASS="OPTION">-3</CODE> 禁止显示第<TTCLASS="LITERAL">3</TT>列 (译者: 在File3中的行)</P></LI><LI><P><CODECLASS="OPTION">-12</CODE> 禁止第<TTCLASS="LITERAL">1</TT>列和第<TTCLASS="LITERAL">2</TT>列, 等等. (译者: 就是说选项可以组合)</P></LI></UL>	    </P></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="FAUTILS1"></A>Utilities</B></P><DL><DT><BCLASS="COMMAND">basename</B></DT><DD><P>从文件名中去掉路径信息, 只打印出文件名. 			  结构<KBDCLASS="USERINPUT">basename		$0</KBD>可以让脚本获得它自己的名字, 也就是, 它被调用的名字. 	可以用来显示<SPANCLASS="QUOTE">"用法"</SPAN>信息, 	      比如如果你调用脚本的时候缺少参数, 可以使用如下语句:               <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;echo "Usage: `basename $0` arg1 arg2 ... argn"</PRE></FONT></TD></TR></TABLE>	    </P></DD><DT><BCLASS="COMMAND">dirname</B></DT><DD><P>从带路径的文件名字符串中去掉文件名(<BCLASS="COMMAND">basename</B>), 只打印出路径信息. </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">basename</B>和<BCLASS="COMMAND">dirname</B>可以操作任意字符串. 				它们的参数不一定是一个真正存在的文件, 甚至可以不是一个文件名. 		(请参考<AHREF="contributed-scripts.html#DAYSBETWEEN">例子 A-7</A>). </P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="EX35"></A><P><B>例子 12-33. <BCLASS="COMMAND">basename</B>和<BCLASS="COMMAND">dirname</B></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;  3&nbsp;a=/home/bozo/daily-journal.txt  4&nbsp;  5&nbsp;echo "Basename of /home/bozo/daily-journal.txt = `basename $a`"  6&nbsp;echo "Dirname of /home/bozo/daily-journal.txt = `dirname $a`"  7&nbsp;echo  8&nbsp;echo "My own home is `basename ~/`."         # `basename ~` 也可以.  9&nbsp;echo "The home of my home is `dirname ~/`."  # `dirname ~`  也可以. 10&nbsp; 11&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><BCLASS="COMMAND">split</B>, <BCLASS="COMMAND">csplit</B></DT><DD><P>将一个文件分割为几个小段的工具. 			  这些命令通常会将大的文件分割, 然后备份到软盘上, 			  或者是为了将大文件切成合适的尺寸, 然后用email上传. 	      </P><P><BCLASS="COMMAND">csplit</B>命令会根据<EM>上下文</EM>来切割文件, 			  切割的位置将会发生在模式匹配的地方. 	      </P></DD><DT><BCLASS="COMMAND">sum</B>, <BCLASS="COMMAND">cksum</B>, <ANAME="MD5SUMREF"></A><BCLASS="COMMAND">md5sum</B>, <BCLASS="COMMAND">sha1sum</B></DT><DD><P>这些都是用来产生checksum的工具. 			<EM>checksum</EM>是对文件的内容进行数学计算而得到的, 			它的目的是用来检验文件的完整性, 			出于安全目的一个脚本可能会有一个checksum列表, 			这样可以确保关键系统文件的内容不会被修改或损坏. 			对于需要安全性的应用来说, 应该使用<BCLASS="COMMAND">md5sum</B> (<BCLASS="COMMAND">m</B>essage	      <BCLASS="COMMAND">d</B>igest <BCLASS="COMMAND">5</B>		  check<BCLASS="COMMAND">sum</B>)命令, 		  或者使用更好更新的<BCLASS="COMMAND">sha1sum</B>命令(安全Hash算法). 	  </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">cksum /boot/vmlinuz</KBD><SAMPCLASS="COMPUTEROUTPUT">1670054224 804083 /boot/vmlinuz</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">echo -n "Top Secret" | cksum</KBD><SAMPCLASS="COMPUTEROUTPUT">3391003827 10</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">md5sum /boot/vmlinuz</KBD><SAMPCLASS="COMPUTEROUTPUT">0f43eccea8f09e0a0b2b5cf1dcf333ba  /boot/vmlinuz</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">echo -n "Top Secret" | md5sum</KBD><SAMPCLASS="COMPUTEROUTPUT">8babc97a6f62a4649716f4df8d61728f  -</SAMP>	      </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">cksum</B>将会显示目标尺寸(以字节为单位), 	    目标可以是<TTCLASS="FILENAME">stdout</TT>, 也可以是文件. </P><P><BCLASS="COMMAND">md5sum</B>和<BCLASS="COMMAND">sha1sum</B>命令在它们收到来自于<TTCLASS="FILENAME">stdout</TT>的输入的时候, 	    显示一个<AHREF="special-chars.html#DASHREF2">dash</A>. 	    </P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="FILEINTEGRITY"></A><P><B>例子 12-34. 检查文件完整性</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# file-integrity.sh: 检查一个给定目录下的文件  3&nbsp;#                    是否被改动了.   4&nbsp;  5&nbsp;E_DIR_NOMATCH=70  6&nbsp;E_BAD_DBFILE=71  7&nbsp;  8&nbsp;dbfile=File_record.md5  9&nbsp;# 存储记录的文件名(数据库文件). 10&nbsp; 11&nbsp; 12&nbsp;set_up_database () 13&nbsp;{ 14&nbsp;  echo ""$directory"" &#62; "$dbfile" 15&nbsp;  # 把目录名写到文件的第一行.  16&nbsp;  md5sum "$directory"/* &#62;&#62; "$dbfile" 17&nbsp;  # 在文件中附上md5 checksum和filename.  18&nbsp;} 19&nbsp; 20&nbsp;check_database () 21&nbsp;{ 22&nbsp;  local n=0 23&nbsp;  local filename 24&nbsp;  local checksum 25&nbsp; 26&nbsp;  # ------------------------------------------- # 27&nbsp;  #  这个文件检查其实是不必要的, 28&nbsp;  #+ 但是能更安全一些. 29&nbsp; 30&nbsp;  if [ ! -r "$dbfile" ] 31&nbsp;  then 32&nbsp;    echo "Unable to read checksum database file!" 33&nbsp;    exit $E_BAD_DBFILE 34&nbsp;  fi 35&nbsp;  # ------------------------------------------- # 36&nbsp; 37&nbsp;  while read record[n] 38&nbsp;  do 39&nbsp; 40&nbsp;    directory_checked="${record[0]}" 41&nbsp;    if [ "$directory_checked" != "$directory" ] 42&nbsp;    then 43&nbsp;      echo "Directories do not match up!" 44&nbsp;      # 换个目录试一下.  45&nbsp;      exit $E_DIR_NOMATCH 46&nbsp;    fi 47&nbsp; 48&nbsp;    if [ "$n" -gt 0 ]   # 不是目录名.  49&nbsp;    then 50&nbsp;      filename[n]=$( echo ${record[$n]} | awk '{ print $2 }' ) 51&nbsp;      #  md5sum向后写记录,  52&nbsp;      #+ 先写checksum, 然后写filename.  53&nbsp;      checksum[n]=$( md5sum "${filename[n]}" ) 54&nbsp; 55&nbsp; 56&nbsp;      if [ "${record[n]}" = "${checksum[n]}" ] 57&nbsp;      then 58&nbsp;        echo "${filename[n]} unchanged." 59&nbsp; 60&nbsp;      elif [ "`basename ${filename[n]}`" != "$dbfile" ] 61&nbsp;             #  跳过checksum数据库文件,  62&nbsp;             #+ 因为在每次调用脚本它都会被修改.  63&nbsp;	     #  --- 64&nbsp;	     #  这不幸的意味着当我们在$PWD中运行这个脚本时侯,  65&nbsp;	     #+ 篡改这个checksum数 66&nbsp;	     #+ 据库文件将不会被检测出来.  67&nbsp;	     #  练习: 修正这个问题. 68&nbsp;	then 69&nbsp;          echo "${filename[n]} : CHECKSUM ERROR!" 70&nbsp;        # 从上次的检查之后, 文件已经被修改.  71&nbsp;      fi 72&nbsp; 73&nbsp;      fi 74&nbsp; 75&nbsp; 76&nbsp; 77&nbsp;    let "n+=1" 78&nbsp;  done &#60;"$dbfile"       # 从checksum数据库文件中读.   79&nbsp; 80&nbsp;}   81&nbsp; 82&nbsp;# =================================================== # 83&nbsp;# main () 84&nbsp; 85&nbsp;if [ -z  "$1" ] 86&nbsp;then 87&nbsp;  directory="$PWD"      #  如果没指定参数的话,  88&nbsp;else                    #+ 那么就使用当前的工作目录.  89&nbsp;  directory="$1" 90&nbsp;fi   91&nbsp; 92&nbsp;clear                   # 清屏. 93&nbsp;echo " Running file integrity check on $directory" 94&nbsp;echo 95&nbsp; 96&nbsp;# ------------------------------------------------------------------ # 97&nbsp;  if [ ! -r "$dbfile" ] # 是否需要建立数据库文件?  98&nbsp;  then 99&nbsp;    echo "Setting up database file, \""$directory"/"$dbfile"\"."; echo100&nbsp;    set_up_database101&nbsp;  fi  102&nbsp;# ------------------------------------------------------------------ #103&nbsp;104&nbsp;check_database          # 调用主要处理函数. 105&nbsp;106&nbsp;echo 107&nbsp;108&nbsp;#  你可能想把这个脚本的输出重定向到文件中, 109&nbsp;#+ 尤其在这个目录中有很多文件的时候. 110&nbsp;111&nbsp;exit 0112&nbsp;113&nbsp;#  如果要对数量非常多的文件做完整性检查, 114&nbsp;#+ 可以考虑一下"Tripwire"包,115&nbsp;#+ http://sourceforge.net/projects/tripwire/.116&nbsp;</PRE></FONT></TD></TR></TABLE><HR></DIV><P>请参考<AHREF="contributed-scripts.html#DIRECTORYINFO">例子 A-19</A>和<AHREF="colorizing.html#HORSERACE">例子 33-14</A>, 			这两个例子展示了<BCLASS="COMMAND">md5sum</B>命令的用法. </P><DIVCLASS="NOTE"><P></P

⌨️ 快捷键说明

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