extmisc.html

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

HTML
2,164
字号
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><HTML><HEAD><TITLE>混杂命令</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINKREL="HOME"TITLE="高级Bash脚本编程指南"HREF="index.html"><LINKREL="UP"TITLE="外部过滤器, 程序和命令"HREF="external.html"><LINKREL="PREVIOUS"TITLE="数学计算命令"HREF="mathc.html"><LINKREL="NEXT"TITLE="系统与管理命令"HREF="system.html"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">高级Bash脚本编程指南: 一本深入学习shell脚本艺术的书籍</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="mathc.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">12. 外部过滤器, 程序和命令</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="system.html"ACCESSKEY="N">下一页</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="EXTMISC">12.9. 混杂命令</A></H1><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="MISCCOMMANDLISTING1"></A>一些不好归类的命令</B></P><DL><DT><BCLASS="COMMAND">jot</B>, <BCLASS="COMMAND">seq</B></DT><DD><P>这些工具用来生成一系列整数, 用户可以指定生成范围. 	      </P><P>每个产生出来的整数一般都占一行, 			  但是可以使用<CODECLASS="OPTION">-s</CODE>选项来改变这种设置. 	      </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">seq 5</KBD><SAMPCLASS="COMPUTEROUTPUT">1 2 3 4 5</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">seq -s : 5</KBD><SAMPCLASS="COMPUTEROUTPUT">1:2:3:4:5</SAMP>	      </PRE></FONT></TD></TR></TABLE>	    </P><P><BCLASS="COMMAND">jot</B>和<BCLASS="COMMAND">seq</B>命令经常用在<AHREF="loops1.html#FORLOOPREF1">for循环</A>中. </P><DIVCLASS="EXAMPLE"><HR><ANAME="EX53"></A><P><B>例子 12-49. 使用<BCLASS="COMMAND">seq</B>命令来产生循环参数</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# 使用"seq"  3&nbsp;  4&nbsp;echo  5&nbsp;  6&nbsp;for a in `seq 80`  # or   for a in $( seq 80 )  7&nbsp;# 与	for a in 1 2 3 4 5 ... 80   相同(少敲了好多字!).  8&nbsp;# 也可以使用'jot'(如果系统上有的话).   9&nbsp;do 10&nbsp;  echo -n "$a " 11&nbsp;done      # 1 2 3 4 5 ... 80 12&nbsp;# 这也是一个通过使用命令输出 13&nbsp;# 来产生"for"循环中[list]列表的例子.  14&nbsp; 15&nbsp;echo; echo 16&nbsp; 17&nbsp; 18&nbsp;COUNT=80  # 当然, 'seq'也可以使用一个可替换的参数. 19&nbsp; 20&nbsp;for a in `seq $COUNT`  # 或者   for a in $( seq $COUNT ) 21&nbsp;do 22&nbsp;  echo -n "$a " 23&nbsp;done      # 1 2 3 4 5 ... 80 24&nbsp; 25&nbsp;echo; echo 26&nbsp; 27&nbsp;BEGIN=75 28&nbsp;END=80 29&nbsp; 30&nbsp;for a in `seq $BEGIN $END` 31&nbsp;#  传给"seq"两个参数, 从第一个参数开始增长, 32&nbsp;#+ 一直增长到第二个参数为止.  33&nbsp;do 34&nbsp;  echo -n "$a " 35&nbsp;done      # 75 76 77 78 79 80 36&nbsp; 37&nbsp;echo; echo 38&nbsp; 39&nbsp;BEGIN=45 40&nbsp;INTERVAL=5 41&nbsp;END=80 42&nbsp; 43&nbsp;for a in `seq $BEGIN $INTERVAL $END` 44&nbsp;#  传给"seq"三个参数, 从第一个参数开始增长,  45&nbsp;#+ 并以第二个参数作为增量,  46&nbsp;#+ 一直增长到第三个参数为止.  47&nbsp;do 48&nbsp;  echo -n "$a " 49&nbsp;done      # 45 50 55 60 65 70 75 80 50&nbsp; 51&nbsp;echo; echo 52&nbsp; 53&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>一个简单一些的例子:	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#  产生10个连续扩展名的文件,   2&nbsp;#+ 名字分别是 file.1, file.2 . . . file.10.  3&nbsp;COUNT=10  4&nbsp;PREFIX=file  5&nbsp;  6&nbsp;for filename in `seq $COUNT`  7&nbsp;do  8&nbsp;  touch $PREFIX.$filename  9&nbsp;  #  或者, 你可以做一些其他的操作,  10&nbsp;  #+ 比如rm, grep, 等等.  11&nbsp;done</PRE></FONT></TD></TR></TABLE></P><DIVCLASS="EXAMPLE"><HR><ANAME="LETTERCOUNT"></A><P><B>例子 12-50. 字母统计</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# letter-count.sh: 统计一个文本文件中某些字母出现的次数.  3&nbsp;# 由Stefano Palmeri所编写.   4&nbsp;# 经过授权可以使用在本书中.   5&nbsp;# 本书作者做了少许修改.   6&nbsp;  7&nbsp;MINARGS=2          # 本脚本至少需要2个参数.   8&nbsp;E_BADARGS=65  9&nbsp;FILE=$1 10&nbsp; 11&nbsp;let LETTERS=$#-1   # 指定了多少个字母(作为命令行参数). 12&nbsp;                   # (从命令行参数的个数中减1.) 13&nbsp; 14&nbsp; 15&nbsp;show_help(){ 16&nbsp;	   echo 17&nbsp;           echo Usage: `basename $0` file letters   18&nbsp;           echo Note: `basename $0` arguments are case sensitive. 19&nbsp;           echo Example: `basename $0` foobar.txt G n U L i N U x. 20&nbsp;	   echo 21&nbsp;} 22&nbsp; 23&nbsp;# 检查参数个数.  24&nbsp;if [ $# -lt $MINARGS ]; then 25&nbsp;   echo 26&nbsp;   echo "Not enough arguments." 27&nbsp;   echo 28&nbsp;   show_help 29&nbsp;   exit $E_BADARGS 30&nbsp;fi   31&nbsp; 32&nbsp; 33&nbsp;# 检查文件是否存在.  34&nbsp;if [ ! -f $FILE ]; then 35&nbsp;    echo "File \"$FILE\" does not exist." 36&nbsp;    exit $E_BADARGS 37&nbsp;fi 38&nbsp; 39&nbsp; 40&nbsp; 41&nbsp;# 统计字母出现的次数.  42&nbsp;for n in `seq $LETTERS`; do 43&nbsp;      shift 44&nbsp;      if [[ `echo -n "$1" | wc -c` -eq 1 ]]; then             #  检查参数. 45&nbsp;             echo "$1" -\&#62; `cat $FILE | tr -cd  "$1" | wc -c` #  统计.  46&nbsp;      else 47&nbsp;             echo "$1 is not a  single char." 48&nbsp;      fi   49&nbsp;done 50&nbsp; 51&nbsp;exit $? 52&nbsp; 53&nbsp;#  这个脚本在功能上与letter-count2.sh完全相同,  54&nbsp;#+ 但是运行得更快.  55&nbsp;#  为什么? </PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><ANAME="GETOPTY"></A><BCLASS="COMMAND">getopt</B></DT><DD><P><BCLASS="COMMAND">getopt</B>命令将会分析以<AHREF="special-chars.html#DASHREF">破折号</A>开头的命令行选项. 			  这个外部命令与Bash的内建命令<AHREF="internal.html#GETOPTSX">getopts</A>作用相同. 			  通过使用<CODECLASS="OPTION">-l</CODE>标志, 			  <BCLASS="COMMAND">getopt</B>可以处理超长(多个字符的)选项, 	      并且也允许参数重置. </P><DIVCLASS="EXAMPLE"><HR><ANAME="EX33A"></A><P><B>例子 12-51. 使用<BCLASS="COMMAND">getopt</B>来分析命令行选项</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# 使用getopt.   3&nbsp;  4&nbsp;# 尝试使用下边的不同的方法来调用这脚本:   5&nbsp;#   sh ex33a.sh -a  6&nbsp;#   sh ex33a.sh -abc  7&nbsp;#   sh ex33a.sh -a -b -c  8&nbsp;#   sh ex33a.sh -d  9&nbsp;#   sh ex33a.sh -dXYZ 10&nbsp;#   sh ex33a.sh -d XYZ 11&nbsp;#   sh ex33a.sh -abcd 12&nbsp;#   sh ex33a.sh -abcdZ 13&nbsp;#   sh ex33a.sh -z 14&nbsp;#   sh ex33a.sh a 15&nbsp;# 解释上面每一次调用的结果.  16&nbsp; 17&nbsp;E_OPTERR=65 18&nbsp; 19&nbsp;if [ "$#" -eq 0 ] 20&nbsp;then   # 脚本需要至少一个命令行参数.  21&nbsp;  echo "Usage $0 -[options a,b,c]" 22&nbsp;  exit $E_OPTERR 23&nbsp;fi   24&nbsp; 25&nbsp;set -- `getopt "abcd:" "$@"` 26&nbsp;# 为命令行参数设置位置参数.  27&nbsp;# 如果使用"$*"来代替"$@"的话, 会发生什么?  28&nbsp; 29&nbsp;while [ ! -z "$1" ] 30&nbsp;do 31&nbsp;  case "$1" in 32&nbsp;    -a) echo "Option \"a\"";; 33&nbsp;    -b) echo "Option \"b\"";; 34&nbsp;    -c) echo "Option \"c\"";; 35&nbsp;    -d) echo "Option \"d\" $2";; 36&nbsp;     *) break;; 37&nbsp;  esac 38&nbsp; 39&nbsp;  shift 40&nbsp;done 41&nbsp; 42&nbsp;#  通常来说在脚本中使用内建的'getopts'命令,  43&nbsp;#+ 会比使用'getopt'好一些.  44&nbsp;#  参考"ex33.sh". 45&nbsp; 46&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>请参考<AHREF="string-manipulation.html#GETOPTSIMPLE">例子 9-13</A>, 				这是对<BCLASS="COMMAND">getopt</B>命令的一个简单模拟. </P></DD><DT><ANAME="RUNPARTSREF"></A><BCLASS="COMMAND">run-parts</B></DT><DD><P><BCLASS="COMMAND">run-parts</B>命令		<ANAME="AEN10535"HREF="#FTN.AEN10535"><SPANCLASS="footnote">[1]</SPAN></A>	      	     将会执行目标目录中所有的脚本, 	     这些脚本会以ASCII码的循序进行排列. 	     当然, 这些脚本都需要具有可执行权限. </P><P><AHREF="system.html#CRONREF">cron</A> <AHREF="communications.html#DAEMONREF">幽灵进程</A>会调用<BCLASS="COMMAND">run-parts</B>来运行<TTCLASS="FILENAME">/etc/cron.*</TT>下的所有脚本. </P></DD><DT><BCLASS="COMMAND">yes</B></DT><DD><P><BCLASS="COMMAND">yes</B>命令的默认行为是向<TTCLASS="FILENAME">stdout</TT>连续不断的输出字符<SAMPCLASS="COMPUTEROUTPUT">y</SAMP>, 		每个<SAMPCLASS="COMPUTEROUTPUT">y</SAMP>单独占一行. 	      可以使用<BCLASS="KEYCAP">control</B>-<BCLASS="KEYCAP">c</B>来结束输出. 		  如果想换一个输出字符的话, 		  可以使用<KBDCLASS="USERINPUT">yes different string</KBD>, 		  这样就会连续不断的输出<SAMPCLASS="COMPUTEROUTPUT">different string</SAMP>到<TTCLASS="FILENAME">stdout</TT>. 		  那么这样的命令究竟能用来做什么呢? 		  在命令行或者脚本中, 	      <BCLASS="COMMAND">yes</B>的输出可以通过重定向或管道来传递给一些命令, 这些命令的特点是需要用户输入来进行交互. 		  事实上, 这个命令可以说是<BCLASS="COMMAND">expect</B>命令(译者注: 		  这个命令本书未介绍, 		  一个自动实现交互的命令)的一个简化版本. </P><P><KBDCLASS="USERINPUT">yes | fsck /dev/hda1</KBD>将会以非交互的形式运行<BCLASS="COMMAND">fsck</B>(译者注: 		  因为需要用户输入的y全由yes命令搞定了)(小心使用!). </P><P><KBDCLASS="USERINPUT">yes | rm -r dirname</KBD> 与	     <KBDCLASS="USERINPUT">rm -rf dirname</KBD> 效果相同(小心使用!). </P><DIVCLASS="WARNING"><P></P><TABLECLASS="WARNING"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/warning.gif"HSPACE="5"ALT="Warning"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>当用<BCLASS="COMMAND">yes</B>命令的管道形式来使用一些可能具有潜在危险的系统命令的时候一定要深思熟虑, 	     比如<AHREF="system.html#FSCKREF">fsck</A>或<AHREF="system.html#FDISKREF">fdisk</A>. 		 可能会产生一些令人意外的副作用. </P></TD></TR></TABLE></DIV><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">yes</B>命令也可用来分析变量. 	       比如: </P><P>	        <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">yes $BASH_VERSION</KBD><SAMPCLASS="COMPUTEROUTPUT">3.00.16(1)-release 3.00.16(1)-release 3.00.16(1)-release 3.00.16(1)-release 3.00.16(1)-release . . .</SAMP>	      </PRE></FONT></TD></TR></TABLE>	        </P><P>这个<SPANCLASS="QUOTE">"特性"</SPAN>估计也不会特别有用. </P></TD></TR></TABLE></DIV></DD><DT><BCLASS="COMMAND">banner</B></DT><DD><P>将会把传递进来的参数字符串用一个ASCII字符(默认是'#')给画出来(就是将多个'#'拼出一副字符的图形), 			  然后输出到<TTCLASS="FILENAME">stdout</TT>. 			  可以作为硬拷贝重定向到打印机上. 		  (译者注: 可以使用-w 选项设置宽度.) </P></DD><DT><BCLASS="COMMAND">printenv</B></DT><DD><P>显示某个特定用户所有的<AHREF="othertypesv.html#ENVREF">环境变量</A>. </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"

⌨️ 快捷键说明

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