extmisc.html
来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 2,164 行 · 第 1/3 页
HTML
2,164 行
>bash$ </SAMP><KBDCLASS="USERINPUT">objdump -d /bin/ls</KBD><SAMPCLASS="COMPUTEROUTPUT">/bin/ls: file format elf32-i386 Disassembly of section .init: 080490bc <.init>: 80490bc: 55 push %ebp 80490bd: 89 e5 mov %esp,%ebp . . .</SAMP> </PRE></FONT></TD></TR></TABLE> </P></DD><DT><BCLASS="COMMAND">mcookie</B></DT><DD><P>这个命令会产生一个<SPANCLASS="QUOTE">"magic cookie"</SPAN>, 这是一个128-bit(32-字符)的伪随机16进制数字, 这个数字一般都用来作为X server的鉴权<SPANCLASS="QUOTE">"签名"</SPAN>. 这个命令还可以用来在脚本中作为一种生成随机数的手段, 当然这是一种<SPANCLASS="QUOTE">"小吃店"</SPAN>(译者注: 虽然不太正统, 但是方便快捷)的风格. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 random000=$(mcookie)</PRE></FONT></TD></TR></TABLE> </P><P>当然, 要想达到同样的目的还可以使用<AHREF="filearchiv.html#MD5SUMREF">md5</A>命令. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 # 产生关于脚本自身的md5 checksum. 2 random001=`md5sum $0 | awk '{print $1}'` 3 # 使用 'awk' 来去掉文件名. </PRE></FONT></TD></TR></TABLE> </P><P><BCLASS="COMMAND">mcookie</B>命令还给出了另一种产生<SPANCLASS="QUOTE">"唯一"</SPAN>文件名的方法. </P><DIVCLASS="EXAMPLE"><HR><ANAME="TEMPFILENAME"></A><P><B>例子 12-56. 文件名产生器</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # tempfile-name.sh: 临时文件名产生器 3 4 BASE_STR=`mcookie` # 32-字符的magic cookie. 5 POS=11 # 字符串中随便的一个位置. 6 LEN=5 # 取得$LEN长度连续的字符串. 7 8 prefix=temp # 最终的一个"临时"文件. 9 # 如果想让这个文件更加"唯一", 10 #+ 可以对这个前缀也采用下边的方法进行生成. 11 12 suffix=${BASE_STR:POS:LEN} 13 # 提取从第11个字符之后的长度为5的字符串. 14 15 temp_filename=$prefix.$suffix 16 # 构造文件名. 17 18 echo "Temp filename = "$temp_filename"" 19 20 # sh tempfile-name.sh 21 # Temp filename = temp.e19ea 22 23 # 与使用'date'命令(参考 ex51.sh)来创建"唯一"文件名 24 #+ 的方法相比较. 25 26 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><BCLASS="COMMAND">units</B></DT><DD><P>这个工具用来在不同的计量单位之间互相转换. 当你在交互模式下正常调用时, 会发现在脚本中<BCLASS="COMMAND">units</B>命令也是非常有用的. </P><DIVCLASS="EXAMPLE"><HR><ANAME="UNITCONVERSION"></A><P><B>例子 12-57. 将长度单位-米, 转化为英里</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # unit-conversion.sh 3 4 5 convert_units () # 通过参数取得需要转换的单位. 6 { 7 cf=$(units "$1" "$2" | sed --silent -e '1p' | awk '{print $2}') 8 # 除了真正需要转换的部分保留下来外,其他的部分都去掉. 9 echo "$cf" 10 } 11 12 Unit1=miles 13 Unit2=meters 14 cfactor=`convert_units $Unit1 $Unit2` 15 quantity=3.73 16 17 result=$(echo $quantity*$cfactor | bc) 18 19 echo "There are $result $Unit2 in $quantity $Unit1." 20 21 # 如果你传递了两个不匹配的单位会发生什么? 22 #+ 比如分别传入"英亩"和"英里"? 23 24 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><BCLASS="COMMAND">m4</B></DT><DD><P>一个隐藏的财宝, <BCLASS="COMMAND">m4</B>是一个强大的宏处理过滤器, <ANAME="AEN10855"HREF="#FTN.AEN10855"><SPANCLASS="footnote">[5]</SPAN></A> 差不多可以说是一种语言了. 虽然最开始这个工具是用来作为<EM>RatFor</EM>的预处理器而编写的, 但是后来证明<BCLASS="COMMAND">m4</B>即使作为独立的工具来使用也是非常有用的. 事实上, <BCLASS="COMMAND">m4</B>结合了许多工具的功能, 比如<AHREF="internal.html#EVALREF">eval</A>, <AHREF="textproc.html#TRREF">tr</A>, 和<AHREF="awk.html#AWKREF">awk</A>, 除此之外, 它还使得宏扩展变得更加容易. </P><P>在2004年4月的<AHREF="http://www.linuxjournal.com"TARGET="_top"><ICLASS="CITETITLE">Linux Journal</I></A>问题列表中有一篇关于<BCLASS="COMMAND">m4</B>命令用法的好文章. </P><DIVCLASS="EXAMPLE"><HR><ANAME="M4"></A><P><B>例子 12-58. 使用m4</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # m4.sh: 使用m4宏处理器 3 4 # 字符串操作 5 string=abcdA01 6 echo "len($string)" | m4 # 7 7 echo "substr($string,4)" | m4 # A01 8 echo "regexp($string,[0-1][0-1],\&Z)" | m4 # 01Z 9 10 # 算术操作 11 echo "incr(22)" | m4 # 23 12 echo "eval(99 / 3)" | m4 # 33 13 14 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><BCLASS="COMMAND">doexec</B></DT><DD><P><BCLASS="COMMAND">doexec</B>命令允许将一个随便的参数列表传递到一个 <EM>二进制可执行文件</EM>中. 比较特殊的, 甚至可以传递<CODECLASS="VARNAME">argv[0]</CODE>(相当于脚本中的<AHREF="othertypesv.html#POSPARAMREF1">$0</A>), 这样就可以使用不同的名字来调用这个可执行文件, 并且通过不同的调用名字, 还可以让这个可执行文件执行不同的动作. 这也可以说是一种将参数传递到可执行文件中的比较绕圈子的做法. </P><P>比如, <TTCLASS="FILENAME">/usr/local/bin</TT>目录可能包含一个<SPANCLASS="QUOTE">"aaa"</SPAN>的二进制文件. 使用<BCLASS="COMMAND">doexec /usr/local/bin/aaa list</B>可以<EM>列出</EM>当前工作目录下所有以<SPANCLASS="QUOTE">"a"</SPAN>开头的文件, 而使用<BCLASS="COMMAND">doexec /usr/local/bin/aaa delete </B>将会<EM>删除</EM>这些文件. </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>可执行文件的不同行为必须定义在可执行文件自身的代码中, 可以使用如下的shell脚本来做类比: <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 case `basename $0` in 2 "name1" ) do_something;; 3 "name2" ) do_something_else;; 4 "name3" ) do_yet_another_thing;; 5 * ) bail_out;; 6 esac</PRE></FONT></TD></TR></TABLE></P></TD></TR></TABLE></DIV></DD><DT><BCLASS="COMMAND">dialog</B></DT><DD><P><AHREF="assortedtips.html#DIALOGREF">dialog</A>工具集提供了一种从脚本中调用交互对话框的方法. <BCLASS="COMMAND">dialog</B>更好的变种版本是 -- <BCLASS="COMMAND">gdialog</B>, <BCLASS="COMMAND">Xdialog</B>, 和<BCLASS="COMMAND">kdialog</B> -- 事实上是调用X-Windows的界面工具集. 请参考<AHREF="assortedtips.html#DIALOG">例子 33-19</A>. </P></DD><DT><BCLASS="COMMAND">sox</B></DT><DD><P><BCLASS="COMMAND">sox</B>命令, 也就是<SPANCLASS="QUOTE">"<EM>so</EM>und e<EM>x</EM>change"</SPAN>命令, 可以进行声音文件的转换. 事实上, 可执行文件<TTCLASS="FILENAME">/usr/bin/play</TT>(现在不建议使用)只不过是<EM>sox</EM>的一个shell包装器而已. </P><P>举个例子, <BCLASS="COMMAND">sox soundfile.wav soundfile.au</B>将会把一个WAV文件转换成(Sun音频格式)AU声音文件. </P><P>Shell脚本非常适合于使用<BCLASS="COMMAND">sox</B>的声音操作来批处理声音文件. 比如, <AHREF="http://osl.iu.edu/~tveldhui/radio/"TARGET="_top"> Linux Radio Timeshift HOWTO</A>和<AHREF="http://savannah.nongnu.org/projects/audiodo"TARGET="_top">MP3do Project</A>. </P></DD></DL></DIV></DIV><H3CLASS="FOOTNOTES">注意事项</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN10535"HREF="extmisc.html#AEN10535"><SPANCLASS="footnote">[1]</SPAN></A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>这个工具事实上是从Debian Linux发行版中的一个脚本借鉴过来的. </P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN10624"HREF="extmisc.html#AEN10624"><SPANCLASS="footnote">[2]</SPAN></A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P><EM>打印队列</EM>就是<SPANCLASS="QUOTE">"在线等待"</SPAN>打印的作业组. </P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN10686"HREF="extmisc.html#AEN10686"><SPANCLASS="footnote">[3]</SPAN></A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>对于本话题的一个完美的介绍, 请参考Andy Vaught的文章, <AHREF="http://www2.linuxjournal.com/lj-issues/issue41/2156.html"TARGET="_top">命名管道的介绍</A>, 这是<AHREF="http://www.linuxjournal.com"TARGET="_top"><ICLASS="CITETITLE">Linux Journal</I>1997年9月的一个主题</A>. </P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN10719"HREF="extmisc.html#AEN10719"><SPANCLASS="footnote">[4]</SPAN></A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P><ACRONYMCLASS="ACRONYM">EBCDIC</ACRONYM> (发音是<SPANCLASS="QUOTE">"ebb-sid-ick"</SPAN>)是单词(Extended Binary Coded Decimal Interchange Code)的首字母缩写. 这是IBM的数据格式, 现在已经不常见了. <BCLASS="COMMAND">dd</B>命令的<CODECLASS="OPTION">conv=ebcdic</CODE>选项有一种比较古怪的用法, 那就是对一个文件进行快速容易但不太安全的编码. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 cat $file | dd conv=swab,ebcdic > $file_encrypted 2 # 编码(看起来好像没什么用). 3 # 应该交换字节(swab), 有点晦涩. 4 5 cat $file_encrypted | dd conv=swab,ascii > $file_plaintext 6 # 解码. </PRE></FONT></TD></TR></TABLE> </P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN10855"HREF="extmisc.html#AEN10855"><SPANCLASS="footnote">[5]</SPAN></A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P><EM>宏</EM>是一个符号常量, 将会被扩展成一个命令字符串或者一系列的参数进行操作. </P></TD></TR></TABLE><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="mathc.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">首页</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="system.html"ACCESSKEY="N">下一页</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">数学计算命令</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="external.html"ACCESSKEY="U">上一级</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">系统与管理命令</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?