shell基础知识

附:Linux终端常用快捷键:
Ctrl + d       删除一个字符,相当于通常的Delete键(命令行若无任何字符,则相当于exit;处理多行标准输入时也表示EOF )
Ctrl + h       退格删除一个字符,相当于通常的Backspace键
Ctrl + u       删除光标之前到行首的字符
Ctrl + k       删除光标之前到行尾的字符
Ctrl + c       取消当前行输入的命令,相当于Ctrl + Break
Ctrl + a       光标移动到行首(Ahead of line),相当于通常的Home键
Ctrl + e       光标移动到行尾(End of line)
Ctrl + f       光标向前(Forward)移动一个字符位置
Ctrl + b       光标往回(Backward)移动一个字符位置
Ctrl + l       清屏,相当于执行clear命令
Ctrl + p       调出命令历史中的前一条(Previous)命令,相当于通常的上箭头
Ctrl + n       调出命令历史中的下一条(Next)命令,相当于通常的上箭头
Ctrl + r       显示:号提示,根据用户输入查找相关历史命令(reverse-i-search)

1.什么是shell
   当一个用户登录Linux系统之后,系统初始化程序init就为每一个用户运行一个称为shell(外壳)的程序。那么,shell是什么呢?确切一点说,shell就是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动、挂起、停止甚至是编写一些程序。
   当用户使用Linux时是通过命令来完成所需工作的。一个命令就是用户和shell之间对话的一个基本单位,它是由多个字符组成并以换行结束的字符串。shell解释用户输入的命令,就象DOS里的command.com所做的一样,所不同的是,在DOS中,command.com只有一个,而在Linux下比较流行的shell有好几个,每个shell都各有千秋。一般的Linux系统都将bash作为默认的shell。
2.几种流行的shell对比
   目前流行的shell有ash、bash、ksh、csh、zsh等,你 可以用下面的命令来查看你自己的shell类型:
#echo $SHELL
$SHELL是一个环境变量,它记录用户所使用的shell类型。你可以用命令:
#shell-name
   来转换到别的shell,这里shell-name是你想要尝试使用的shell的名称,如ash等。这个命令为用户又启动了一个shell,这个shell在最初登录的那个shell之后,称为下级的shell或子shell。使用命令:
$exit
   可以退出这个子shell。

   使用不同的shell的原因在于它们各自都有自己的特点,下面作一个简单的介绍:

一、ash
   ash shell是由Kenneth Almquist编写的,Linux中占用系统资源最少的一个小shell,它只包含24个内部命令,因而使用起来很不方便。

二、bash
   bash是Linux系统默认使用的shell,它由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的缩写,内部命令一共有40个。Linux使用它作为默认的shell是因为它有诸如以下的特色: 
   可以使用类似DOS下面的doskey的功能,用方向键查阅和快速输入并修改命令。
   自动通过查找匹配的方式给出以某字符串开头的命令。
   包含了自身的帮助功能,你只要在提示符下面键入help就可以得到相关的帮助。


三、ksh
   ksh是Korn shell的缩写,由Eric Gisin编写,共有42条内部命令。该shell最大的优点是几乎和商业发行版的ksh完全兼容,这样就可以在不用花钱购买商业版本的情况下尝试商业版本的性能了。

四、csh
   csh是Linux比较大的内核,它由以William Joy为代表的共计47位作者编成,共有52个内部命令。该shell其实是指向/bin/tcsh这样的一个shell,也就是说,csh其实就是tcsh。

五、zch
   zch是Linux最大的shell之一,由Paul Falstad完成,共有84个内部命令。如果只是一般的用途,是没有必要安装这样的shell的。
3.shell脚本编程语言与编译型语言的差异
   许多中型、大型的程序都是用编译型语言写成,例如Fortran、Ada、Pascal、C、C++或Java。这类程序只要从源代码(source code)转换成目标代码(object code),便能直接通过计算机来执行(注1)。

   编译型语言的好处是高效,缺点则是:它们多半运作于底层,所处理的是字节、整数、浮点数或是其他机器层级的对象。例如,在C++里,就很难进行“将一个目录里所有的文件复制到另一个目录中”之类的简单操作。

   脚本编程语言通常是解释型(interpreted)的。这类程序的执行,是由解释器(interpreter)读入程序代码,并将其转换成内部的形式,再执行(注2)。请注意,解释器本身是一般的编译型程序。

   注1:这种说法在Java上并不完全正确,不过已相当接近我们所说的情况了
4.为什么要使用shell脚本
   使用脚本编程语言的好处是,它们多半运行在比编译型语言还高的层级,能够轻易处理文件与目录之类的对象。缺点是:它们的效率通常不如编译型语言。不过权衡之下,通常使用脚本编程还是值得的:花一个小时写成的简单脚本,同样的功能用C或C++来编写实现,可能需要两天,而且一般来说,脚本执行的速度已经够快了,快到足以让人忽略它性能上的问题。脚本编程语言的例子有awk、Perl、Python、Ruby与Shell。

    因为Shell似乎是各UNIX系统之间通用的功能,并且经过了POSIX的标准化。因此,Shell脚本只要“用心写”一次,即可应用到很多系统上。因此,之所以要使用Shell脚本是基于: 
   简单性:Shell是一个高级语言;通过它,你可以简洁地表达复杂的操作。
   可移植性:使用POSIX所定义的功能,可以做到脚本无须修改就可在不同的系统上执行。
   开发容易:可以在短时间内完成一个功能强大又妤用的脚本。
5.如何运行shell命令?第一行为什么是#!/bin/sh
  执行的方法常见的有两种
  一种是sh +shell脚本命令
  
  另一种是. +shell脚本命令,但是这种方法最大的不便就是:一个文件能否运行取决于该文件的内容本身可执行且该文件具有执行权
      chmod +x test.sh
      ./test.sh
      “# !/bin/bash”,其中#
   表示该行是注释,叹号“!”告诉shell运行叹号之后的命令并用文件的其余部分作为输入,也就是运行/bin/bash并让/bin/bash去执行shell程序的内容。
   这里还涉及到脚本解释器:
   sh
   即Bourne shell,POSIX(Portable Operating System Interface)标准的shell解释器,它的二进制文件路径通常是/bin/sh,由Bell Labs开发。
   
    bash
    Bash是Bourne shell的替代品,属GNU Project,二进制文件路径通常是/bin/bash。业界通常混用bash、sh、和shell,比如你会经常在招聘运维工程师的文案中见到:熟悉Linux Bash编程,精通Shell编程。
    “#!”是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行。而解释器就如上
6.shell变量的基础——shell自定义的变量
  一、Shell定义变量需要遵循的规则
   Shell编程中,使用变量无需事先声明,同时变量名的命名须遵循如下规则:
    首个字符必须为字母(a-z,A-Z)
    中间不能有空格,可以使用下划线(_)
    不能使用标点符号
    不能使用bash里的关键字(可用help命令查看保留关键字)
    注释 :以“#”开头的行就是注释,会被解释器忽略
  二、shell变量赋值
   需要给变量赋值时,可以这么写:
   变量名=值 
  三、shell变量的引用
   要取用一个变量的值,只需在变量名前面加一个$ ( 注意: 给变量赋值的时候,不能在"="两边留空格 )。例如:
   #!/bin/sh
   # 对变量赋值:
   a="hello world"  #等号两边均不能有空格存在
   # 打印变量a的值:
   echo "A is:" $a
   注:上边的#号为注释,将在后边讲到。

   挑个自己喜欢的编辑器,输入上述内容,并保存为文件first,然后执行 chmod +x first 使其可执行,最后输入 ./first 执行该脚本。其输出结果如下:
    A is: hello world

   有时候变量名可能会和其它文字混淆,比如:
    num=2
    echo "this is the $numnd"

   上述脚本并不会输出"this is the 2nd"而是"this is the ";这是由于shell会去搜索变量numnd的值,而实际上这个变量此时并没有值。这时,我们可以用花括号来告诉shell要打印的是num变量:
    num=2
    echo "this is the ${num}nd"

   其输出结果为:this is the 2nd
   也就是说,当变量后面还有内容时,直接打印是没有结果的,需要给变量添加{}将变量括住(不包括$符号)才可以打印出你想要的结果
 
  注意:shell的默认赋值是字符串赋值。比如:
     var=1
     var=$var+1
     echo $var
  打印出来的不是2而是1+1。为了达到我们想要的效果有以下几种表达方式:
     let "var+=1"
     var=$[$var+1]    
     var=`expr $var+1` #注意加号两边的空格,否则还是按照字符串的方式赋值。
     具体不懂看一下的例子:
     [root@localhost ~]# hy=4
     [root@localhost ~]# let hy/=2
     [root@localhost ~]# echo $hy
     2
     或者是
     [root@localhost ~]# aa=2
     [root@localhost ~]# aa=$[$aa+5]
     [root@localhost ~]# echo $aa
     7
     或者是
     [root@localhost ~]# c=1
     [root@localhost ~]# c=`expr $c + 3`
     [root@localhost ~]# echo $c
     4
  注意:前两种方式在bash下有效,在sh下会出错。

   let表示数学运算,expr用于整数值运算,每一项用空格隔开,$[]将中括号内的表达式作为数学运算先计算结果再输出。
   

   Shell脚本中有许多变量是系统自动设定的,我们将在用到这些变量时再作说明。除了只在脚本内有效的普通shell变量外,还有环境变量,即那些由export关键字处理过的变量。本文不讨论环境变量,因为它们一般只在登录脚本中用到。
7.shell环境变量详解:shell如何设置环境变量
    shell在开始执行时就已经定义了一些和系统的工作环境有关的变量,这些变量用户还可以重新定义,常用的shell环境变量有: 
    HOME:用于保存注册目录的完全路径名。
    PATH:用于保存用冒号分隔的目录路径名,shell将按PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。
    TERM:终端的类型。
    UID:当前用户的标识符,取值是由数字构成的字符串。
    PWD:当前工作目录的绝对路径名,该变量的取值随cd命令的使用而变化。
    PS1:主提示符,在特权用户下,缺省的主提示符是“#”,在普通用户下,缺省的主提示符是“$”。
    PS2:在shell接收用户输入命令的过程中,如果用户在输入行的末尾输入“\”然后回车,或者当用户按回车键时shell判断出用户输入的命令没有结束时,显示这个辅助提示符,提示用户继续输入命令的其余部分,缺省的辅助提示符是“>”
8.shell位置参数应用详解|shell内部参数详解
     一、位置参数
    位置参数是一种在调用shell程序的命令行中按照各自的位置决定的变量,是在程序名之后输入的参数。位置参数之间用空格分隔,shell取第一个位置参数替换程序文件中的,第二个替换,依次类推。是一个特殊的变量,它的内容是当前这个shell程序的文件名,所以,不是一个位置参数,在显示当前所有的位置参数时是不包括的。

    位置参数的值可以用$N得到,N是一个数字,如果为1,即$1.类似C语言中的数组,Linux会把输入的命令字符串分 段并给每段进行标号,标号从0开始。第0号为程序名字,从1开始就表示传递给程序的参数。如$0表示程序的名字,$1表示传递给程序的第一个参数,以此类 推。 After $9, 在位置参数$9之后的参数必须用括号括起来,例如:${10}, ${11}, ${12}。
    比如说:
    [root@localhost ~]# a=(1 2 3 4 5 6 7 8 9 )
    [root@localhost ~]# echo ${a[0]}
     1
    [root@localhost ~]# echo ${a[2]}
    3


    特殊变量$*和$@ 表示所有的位置参数。
  二、内部参数
    上述过程中的$0是一个内部变量,它是必须的,而$1则可有可无。和$0一样的内部变量还有以下几个:
     $# ----传递给程序的总的参数数目
     $? ----上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非0值。
     $* ----传递给程序的所有参数组成的字符串。
     $n ----表示第几个参数,$1 表示第一个参数,$2 表示第二个参数 ...
     $0 ----当前程序的名称
     $@----以"参数1" "参数2" ... 形式保存所有参数
     $$ ----本程序的(进程ID号)PID
     $! ----上一个命令的PID

  列子1:
     if [ -n "$1" ]  #如果$1即参数1不为空,又即存在参数1        # 被测试的变量被双引号引起
       then
       echo "Parameter #1 is $1"  # 使用引号来使#被转义
       fi
     if [ -z "$1" ]  #如果$1即参数1为空(零),又即不存在参数1     
       then
     fi 
     
   数组
   
     [root@localhost ~]# a=(1 2 3 4 5 6 7 8 9 )
     [root@localhost ~]# echo ${a[0]}
      1
     [root@localhost ~]# echo ${a[2]}
     3
9.shell参数置换的变量
   shell提供了参数置换能力以便用户可以根据不同的条件来给变量赋不同的值。参数置换的变量有四种,这些变量通常与某一个位置参数相联系,根据指定的位置参数是否已经设置类决定变量的取值,它们的语法和功能分别如下: 
    变量=$:如果设置了参数,则用参数的值置换变量的值,否则用word置换。即这种变量的值等于某一个参数的值,如果该参数没有设置,则变量就等于word的值。
    变量=$:如果设置了参数,则用参数的值置换变量的值,否则把变量设置成word然后再用word替换参数的值。注意,位置参数不能用于这种方式,因为在shell程序中不能为位置参数赋值。
    变量=$:如果设置了参数,则用参数的值置换变量的值,否则就显示word并从shell中退出,如果省略了word,则显示标准信息。这种变量要求一定等于某一个参数的值,如果该参数没有设置,就显示一个信息,然后退出,因此这种方式常用于出错指示。
    变量=$:如果设置了参数,则用word置换变量,否则不进行置换。

    所有这四种形式中的“参数”既可以是位置参数,也可以是另一个变量,只是用位置参数的情况比较多。
10.shell echo的用法:shell  echo 不换行输出、换行输出|shell echo 换行符、制表符
   bash命令解释程序包含了一些内部命令。内部命令在目录列表时是看不见的,它们由shell本身提供。echo是其中之一。

    命令格式:echo arg
    功能:在屏幕上打印出由arg指定的字符串。

    另外,还可以用echo实现更复杂的输出格式控制:
     1、显示转义字符
      echo "\"It is a test\""
     结果将是: "It is a test"
     同样,双引号也可以省略

   2、显示变量
      read name (在下一行输入ok)
      echo "$name It is a test"
   结果将是: OK It is a test
   [root@localhost ~]# read name
    ok
   [root@localhost ~]# echo "$name it is a test"
    ok it is a test
    为了使交互式操作的界面更加友好,提高易用性,read可以结合“-p”来设置提示信息,以便告知用户应该输入什么内容等相关事项。
   例2:
   [root@localhost hy]# read -p "please tell me a story :"  story
   please tell me a story :123
   [root@localhost hy]# echo $story
   123


   同样双引号也可以省略
   如果变量与其它字符相连的话,需做如下处理:
     read mouth (输入8)
     echo "${mouth}-1-2009"
   结果将是: 8-1-2009

   3、显示换行 因为echo默认是关闭了换行的功能,所以需要加-e开启此功能
     echo "OK!\n"
     echo "It it a test"

   4、显示不换行
     echo "OK!\c"
     echo "It is a test"

   5、显示结果定向至文件
     echo "It is a test" > myfile

   6、原样输出字符串,不进行转义或取变量(用单引号)
     echo '$name\"'

   7、显示命令执行结果
     echo `date`
   结果将显示当前日期
      语 法:echo [-ne][字符串]或 echo [--help][--version]
      补充说明:echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开,并在最后加上换行号。
     参 数:-n 不要在最后自动换行
     -e 若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:
     \a 发出警告声;
     \b 删除前一个字符;
     \c 最后不加上换行符号;
     \f 换行但光标仍旧停留在原来的位置;
     \n 换行且光标移至行首;
     \r 光标移至行首,但不换行;
     \t 插入tab;
     \v 与\f相同;
     \\ 插入\字符;
     \nnn 插入nnn(八进制)所代表的ASCII字符;
     --help 显示帮助
     --version 显示版本信息
     每一个shell支持的echo指令可能都不太相同。
     -n 不输出最后的\n
     -e解释转义字符
     -E不解释转义字符
   从上面可看出,双引号可有可无;单引号主要用在原样输出中。
11.shell test语句用法:文件测试、条件测试、测试脚本、变量测试、测试目录存在
   test命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试,其测试符和相应的功能分别如下:
  一、数值测试:
     -eq:等于则为真
     -ne:不等于则为真
     -gt:大于则为真
     -ge:大于等于则为真
     -lt:小于则为真
     -le:小于等于则为真
  二、字符串测试:
     =:等于则为真
     !=:不相等则为真
     -z字符串:字符串长度伪则为真
     -n字符串:字符串长度不伪则为真
  三、文件测试:
     -e文件名:如果文件存在则为真
     -r文件名:如果文件存在且可读则为真
     -w文件名:如果文件存在且可写则为真
     -x文件名:如果文件存在且可执行则为真
     -s文件名:如果文件存在且至少有一个字符则为真
     -d文件名:如果文件存在且为目录则为真
     -f文件名:如果文件存在且为普通文件则为真
     -c文件名:如果文件存在且为字符型特殊文件则为真
     -b文件名:如果文件存在且为块特殊文件则为真
  另外,Linux还提供了与(“!”)、或(“-o)、非(“-a”)三个逻辑操作符用于将测试条件连接起来,其优先级为:“!”最高,“-a”次之,“-o”最低。

   同时,bash也能完成简单的算术运算,格式如下:
      $[expression]
  例如:
     var1=2
     var2=$[var1*10+1]
  则:
     var2的值为21。
12.shell if else语句的用法详解
    shell程序中的条件分支是通过if条件语句来实现的,其一般格式为:
    if 条件命令串
then
条件为真时的命令串
else
条件为假时的命令串
fi

    大多数情况下,可以使用测试命令来对条件进行测试,比如可以比较字符串、判断文件是否存在及是否可读等等……通常用" [ ] "来表示条件测试,注意这里的空格很重要,要确保方括号前后的空格。
    [ -f "somefile" ] :判断是否是一个文件
    [ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
    [ -n "$var" ] :判断$var变量是否有值
    [ "$a" = "$b" ] :判断$a和$b是否相等

    执行man test可以查看所有测试表达式可以比较和判断的类型。下面是一个简单的if语句:
#!/bin/sh
if [ ${SHELL} = "/bin/bash" ]; then
   echo "your login shell is the bash (bourne again shell)"
else
   echo "your login shell is not bash but ${SHELL}"
fi

    变量$SHELL包含有登录shell的名称,我们拿它和/bin/bash进行比较以判断当前使用的shell是否为bash
    例2:
    #!/bin/bash
read -p "你想成为谁(李白,诗仙,杜甫,诗圣,诗魔,李贺,诗鬼):" shu
if [ $shu -eq 1 ] || [ $shu -eq 2 ]
        then
                echo "做梦吧"
        elif [ $shu -eq 3 ] || [ $shu -eq 4 ]
                then
                        echo "白日梦可能更适合你"
        elif [ $shu -eq 5 ] || [ $shu -eq 6 ]
                then
                        echo "不可能的,但是梦想还是有的"
        elif [ $shu -eq 7 ] || [ $shu -eq 8 ]
                then
                        echo "梦想梦想,当然是做梦都想啦"
        else
        echo "做个好梦,梦里啥都有"
fi
13.shell for 循环语句详解
   for循环对一个变量的可能的值都执行一个命令序列。赋给变量的几个数值既可以在程序内以数值列表的形式提供,也可以在程序以外以位置参数的形式提供。for循环的一般格式为:
for 变量名 [in 数值列表]
do
    若干个命令行
done

    变量名可以是用户选择的任何字符串,如果变量名是var,则在in之后给出的数值将顺序替换循环命令列表中的$var。如果省略了in,则变量var的取值将是位置参数。对变量的每一个可能的赋值都将执行do和done之间的命令列表。

    下面的示例会把A B C分别打印到屏幕上:
     #!/bin/sh
     for var in A B C ; do
         echo "var is $var"
     done

    下面是一个实用的脚本showrpm,其功能是打印一些RPM包的统计信息:
   #!/bin/sh
   # list a content summary of a number of RPM packages
   # USAGE: showrpm rpmfile1 rpmfile2 ...
   # EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
   for rpmpackage in $*; do
      if [ -r "$rpmpackage" ];then
         echo "=============== $rpmpackage =============="
          rpm -qi -p $rpmpackage
      else
         echo "ERROR: cannot read file $rpmpackage"
      fi
   done

   这里出现了第二个特殊变量$*,该变量包含有输入的所有命令行参数值。如果你运行showrpm openssh.rpm w3m.rpm webgrep.rpm,那么 $* 就包含有 3 个字符串,即openssh.rpm, w3m.rpm和 webgrep.rpm。
    
#!/bin/bash
echo "准备倒数5秒:"
for i in $(seq 5 -1 1)
do
  echo -en "\b$i";sleep 1
done
echo -e "\b开始"
    或者是
#!/bin/bash
echo "准备倒数5秒:"
for i in $(seq 5 -1 1)
do
  echo -en "$i";sleep 1
done
echo -e "开始"

    seq后面的5-1代表数字从几到几,而后面的1代表数字替换的时间
    -e表示开启echo中的某些后缀功能
    -n表示不输出最后的/n
    /d表示删除前一个字符
用法:seq [选项]... 尾数
  或:seq [选项]... 首数 尾数
  或:seq [选项]... 首数 增量 尾数
选项:
    -f 指定输出格式
    #seq -f “%3g” 13  数字位数为三位,不足补空格
    #seq -f “%03g” 1 5  数字位数为三位,不足补零
    #seq -f "str%03g" 1 3
    -w 指定输出数字同宽,与-f部分作用相似,不可与-f选项同时使用
    #seq -w  8 12
    -s 指定分隔符,默认分隔符是/n(回车)
    #seq -s  " " 1 5 空格作为分隔符
    #seq -s "`echo -e "\t"`" 1 3 \t作为分隔符
练习2:产生随机十个数
     for i in {0..9};do echo $RANDOM;done
     或者是
     for i in $(seq 10);do echo $RANDOM;done
      $RANDOM 这个变量,可以随机生成 0~32767之间的整数数字;

14.shell while循环语句详解,until语句详解
   while 和 until命令都是用命令的返回状态值来控制循环的。

     While 循环的一般格式为:
        while
          若干个命令行1
        do
          若干个命令行2
        done
#!/bin/bash

i=0

n=0

while [ $i -le 100 ] ;do

 let n=$n+$i

 let i=$i+1

done

echo $n
示例2:
#!/bin/bash
n=`echo $(($RANDOM/1000))`
echo "已生成随机数字!"
while :
do   
    read -p "请猜测随机数字:"  a
    if [ $a -gt $n ]
    then 
        echo -en  "\b数字大了\n"
    elif [ $a -eq $n ]
    then 
        echo -en  "\b回答正确!\n"
        break
    elif [ $a -lt $n ]
    then 
        echo  -en  "\b数字小了\n"
    fi
done

     只要while的“若干个命令行1”中最后一个命令的返回状态为真,while循环就继续执行do...done之间的“若干个命令行2”。(具体详情见txt文本示例4)

     until命令是另一种循环结构,它和while命令相似,其格式如下:
   until
       若干个命令行1
   do
       若干个命令行2
   done
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done
     until循环和while循环的区别在于:while循环在条件为真时继续执行循环,而until则是在条件为假时继续执行循环。

     Shell还提供了true和false两条命令用于建立无限循环结构的需要,它们的返回状态分别是总为0或总为非0
15.shell case 语句用法详解
     和其它编程语言类似,Shell 也支持两种分支结构(选择结构),分别是 if else 语句和 case in 语句。
     当分支较多,并且判断条件比较简单时,使用 case in 语句就比较方便了
     if条件语句用于在两个选项中选定一项,而case条件选择为用户提供了根据字符串或变量的值从多个选项中选择一项的方法,其格式如下:
   case string in
    exp-1)
   若干个命令行1
     ;;
    exp-2)
   若干个命令行2
    ;;
   ……
   *)

   file命令可以辨别出一个给定文件的文件类型,如:file lf.gz,其输出结果为:
   lf.gz: gzip compressed data, deflated, original filename,
   last modified: Mon Aug 27 23:09:18 2001, os: Unix

   我们利用这点写了一个名为smartzip的脚本,该脚本可以自动解压bzip2, gzip和zip 类型的压缩文件:
#!/bin/sh
ftype=`file "$1"`   # Note ' and ` is different
case "$ftype" in
"$1: Zip archive"*)
    unzip "$1" ;;
"$1: gzip compressed"*)
    gunzip "$1" ;;
"$1: bzip2 compressed"*)
    bunzip2 "$1" ;;
*) echo "File $1 can not be uncompressed with smartzip";;
esac
你可能注意到上面使用了一个特殊变量$1,该变量包含有传递给该脚本的第一个参数值。也就是说,当我们运行:
    smartzip articles.zip
    $1 就是字符串 articles.zip。
sed使用率
用法:
    一般用法:
    sed [-neri] '指令' file...
    sed -f scriptsfile file...
选项:
    -n 安静模式,只有经过Sed处理的行才显示出来,其他不显示
    -e 表示直接在命令行模式上进行Sed操作(默认选项);
       进行多项编辑,即对输入行应用多条sed命令时使用
    -f 将Sed的操作写在一个文件里,用的时候“-f filename”就可以按照内容进行Sed操作
    -r 使Sed支持扩展正则表达式(预设支持基础正则表达式)
    -i 直接修改读取的文件内容,而不是输出到终端
    sed 编辑指令的格式如下 :
              [address1[,address2]]function[argument]
    ==addres (指定需要操作的行)==
    1. n1,n2    例:1,100 表示1至100行
        n1行开始,n2行结束
        处理n1行开始到n2行结束的数据
        $符号表示文件最后一行
    2. /RegExp/
        匹配正则表达式
        处理正则表达式匹配的行的数据
    3. /pattern1/,/pattern2/
        pattern1匹配到为行开始
        pattern2匹配到为行结束
        处理pattern1,到pattern2之间所有行数据
    4. n
        指定第n行的
        处理指定第n行的数据
    5. n1,+n  
        n1 为行开始
        +n 开始行向后n行
        处理行开始到向后n行的数据
    ==function(可对数据处理的动作(sed内定函数))==
    d 删除符合条件的行
    D 删除模板块的第一行
    h 拷贝模板块的内容到内存中的缓冲区
    H 追加模板块的内容到内存中的缓冲区
    g 获得内存缓冲区的内容,并替代当前模板块中的文本
    G 获得内存缓冲区的内容,并追加到当前模板块文本的后面
    p 显示符合条件的行
    P (大写) 打印模板块的第一行
    q 退出Sed
    l 列表不能打印字符的清单
    n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
    N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码
    a \"string" 在指定的行后面追加新行,内容为"string"
    i \"string" 在指定的行前面插入新行,内容为"string"
    c \"string" 将处理的数据行,取代内容为"string"
    r file 将指定文件的内容天骄到符合条件的行后
    w file 将指定范围内的内容另存至指定的文件中
    W file (大写)写并追加模板块的第一行到file末尾。
    s/pattern/string/修饰符 查找并替换,默认只替换每行第一次被模式匹配到的字符串
        修饰符:
            g 表示行内全面替换。 
            p 表示打印行。 
            w 表示把行写入一个文件。 
            x 表示互换模板块中的文本和缓冲区中的文本。 
            y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)
            \1 子串匹配标记
            & 已匹配字符串标记
            i 忽略大小写
        特别说明: s///,s###,s@@@都可以,当所使用的分割符号与内容中显示
        的相同时,需使用转义字符转义 ,\1,\2:成组匹配,\1表示匹配第一
        个‘(’,\2表示匹配第二个‘(’
    b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾
    t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾
    T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾  
    ! 表示后面的命令对所有没有被选定的行发生作用。 
    = 打印当前行号码。 
    # 把注释扩展到下一个换行符以前
————————————————
版权声明:本文为CSDN博主「karelcn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/karelcn/article/details/83043559
示例2:
#!/bin/bash
 
#create by guoke
#function number input
 
read -p "please input a number:" num #打印信息提示用户输入,输入信息赋值给num变量
 
case "$num" in
 1)
 echo "The num you input is 1"
 ;;
 [2-5])
 echo "The num you input is 2-5"
 ;;
 [6-9])
 echo "The num you input is 6-9"
 ;;
 *)
 echo "please input number[1-9] int"
 exit;
esac
    *表示任意字符串。
    [abc]表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。
    [m-n]表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。|表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 “abc” 或者 “xyz”
示例2:
#!/bin/bash 
#create by guoke
#function print menu
 
RED_COLOR='\E[1;31m'   #这里是引用了系统中的颜色,并进行了赋值
GREEN_COLOR='\E[1;32m'
YELLOW_COLOR='\E[1;33m'
BLUE_COLOR='\E[1;34m'
RES='\E[0m'
 
echo ' 
#############################
 1.banana
 2.apple
 3.pear
 4.cherry
#############################
'
 
read -p "please select a num:" num
 
case "$num" in
 1)
  echo -e "${YELLOW_COLOR} banana ${RES}"
 ;;
 2)
  echo -e "${RED_COLOR} apple ${RES}"
 ;;
 3)
  echo -e "${GREEN_COLOR} pear ${RES}"
 ;;
 4)
  echo -e "${BLUE_COLOR} cherry ${RES}"
 ;;
 *)
  echo "please input {1|2|3|4}"
esac
输出菜单的另外一种方式
cat<<-EOF
===============================
 1.banana
 2.apple
 3.pear
 4.cherry
===============================
EOF
    

16.shell select语句用法
    扩展:在php,java,c语言中并没有实现select功能
    select表达式是bash的一种扩展应用,擅长于交互式场合。用户可以从一组不同的值中进行选择:
    select var in ... ; do
    break;
    done
   .... now $var can be used ....

下面是一个简单的示例:
#!/bin/sh
echo "What is your  
3) Free BSD
4) Other
#? 1                  #(所以这里要输入的是给出的选项而不是选项的序号)
You have selected Linux
   说明:当程序运行到select语句时,会自动将列表中的所有元素生成为可用1、2、3依次类推的选择列表,并等待用户输入。当用户
   输入值并回车后,select可根据用户输入的值判断并执行后续的命令。
   当然如果用户不做输入,直接回车的话,select将不会退出而是再次生成列等待输入。
   技巧:通常情况下select命令经常和case语句一起使用。
#!/bin/bash
select Day in Mon Tue Wed Thu Fri Sat Sun
do
case $Day in
Mon) echo "Today is Monday";;
Tue) echo "Today is Tuesday";;
Wed) echo "Today is Wednesday";;
Thu) echo "Today is Thursday";;
Fri) echo "Today is Friday";;
Sat|Sum) echo "Today is a rest day";;
*) echo "Error inout,exit now " && break;;
esac
done
17.输出输入重定向
  在Linux中,每一个进程都有三个特殊的文件描述指针:标准输入(standard input,文件描述指针为0)、标准输出(standard output,文件描述指针为1)、标准错误输出(standard error,文件描述指针为2)。

  这三个特殊的文件描述指针使进程在一般情况下接收标准输入终端的输入,同时由标准终端来显示输出,Linux同时也向使用者提供可以使用普通的文件或管道来取代这些标准输入输出设备。

  在shell中,使用者可以利用“>”和“<”来进行输入输出重定向:
  从文件输入   将标准输出重定向为文件 >file or 1>file
  将标准错误重定向为文件 2>file copyright Linuxren.net
  将标准输出追加到文件 >>file
  将标准错误重定向为标准输入 2>&1
  将第一个命令的输入作为第二个文件的输入 cmd1|cmd2
  将第一个文件即作为标准输入也作为标准输出 <>file
  关闭标准输入 0<&-
  关闭标准输出 1>&-
  关闭标准错误 2>&-

例如:
  command>file:将命令的输出结果重定向到一个文件。
  command>&file:将命令的标准错误输出一起重定向到一个文件。
  command>>file:将标准输出的结果追加到文件中。
  command>>&file:将标准输出和标准错误输出的结构都追加到文件中。
18.管道符过滤
   管道pipe同样可以在标准输入输出和标准错误输出间做代替工作,这样一来,可以将某一个程序的输出送到另一个程序的输入,其语法如下:
command1| command2[| command3...]
    也可以连同标准错误输出一起送入管道:
command1| &command2[|& command3...]
   管道过滤器(Pipe-And-Filter)模式
   按照《POSA(面向模式的软件架构)》里的说法,管道过滤器(Pipe-And-Filter)应该属于架构模式,因为它通常决定了一个系统的基 本架构。管道过滤器和生产流水线类似,在生产流水线上,原材料在流水线上经一道一道的工序,最后形成某种有用的产品。在管道过滤器中,数据经过一个一个的 过滤器,最后得到需要的数据。

一、基本的管道过滤器: 


   管道负责数据的传递,它把原始数据传递给第一个过滤器,把一个过滤器的输出传递给下一个过滤器,作为下一个过滤器的输入,重复这个过程直到处理结 束。要注意的是,管道只是对数据传输的抽象,它可能是管道,也可能是其它通信方式,甚至什么都没有(所有过滤器都在原始数据基础上进行处理)。

   过滤器负责数据的处理,过滤器可以有多个,每个过滤器对数据做特定的处理,它们之间没有依赖关系,一个过滤器不必知道其它过滤器的存在。这种松耦合 的设计,使得过滤器只需要实现单一的功能,从而降低了系统的复杂度,也使得过滤器之间依赖最小,从而以更加灵活的组合来实现新的功能。

   编译器就是基于管道过滤器模式设计的: 


   输入:源程序
   预处理:负责宏展开和去掉注释等工作。
   编译:进行词法分析、语法分析、语义分析、代码优化和代码产生。
   汇编:负责把汇编代码转换成机器指令,生成目标文件。
   链接:负责把多个目标文件、静态库和共享库链接成可执行文件/共享库。
  输出:可执行文件/共享库。

二、复合过滤器
   过滤器可以由多个其它过滤器组合起来的,比如上面的“编译”过程可以认为是一个复合过滤器: 

   输入:预处理之后的源代码。
   词法分析:负责将源程序分解成一个一个的token,这些token是组成源程序的基本单元。
   语法分析:把词法分析得到的token解析成语法树。
   语义分析:对语法树进行类型检查等语义分析。
   代码优化:对语法树进行重组和修改,以优化代码的速度和大小。
   代码产生:根据语法树产生汇编代码。
   输出:汇编代码。

三、支持多个输入的过滤器
   过滤器可以有多个输入。比如上面“链接”,它接收多个输入: 

   “链接”过滤器能接收多个数据源,如目标文件、静态库和共享库。

四、具有多个输出的过滤器
   过滤器可以有多个输出。如多媒体播放器的解码过程: 

   输入:AVI文件,包括音频和视频数据。
   分离器:把音频和视频数据分离成两个流,音频数据传递给音频解码器,视频数据传递给视频解码器。
   音频解码器:把压缩的音频数据解码成原始的音频数据。
   视频解码器:把压缩的视频数据解码成原始的图像数据。
   输出:音频数据传递给声卡,图像数据传递给显示器。

   管道过滤器是最贴近程序员生活的模式,也是Unix-like系统的基本设计理念之一。作为Linux下的程序员,我们天天都使用这个模式。比如:
   1、删除当前目录及子目录下的目标文件:
       find -name \*.o|xargs rm –f
   find是过滤器:它找出所有目标文件,它不需要关心查找文件的目的。
   rm是过滤器:它删除找到目标文件,rm不需要关心文件名是如何得来的。

2、查看某个进程的栈的大小
    grep stack /proc/2976/maps|sed -e “s/-/ /”|awk ‘{print strtonum(“0x”$2)-strtonum(“0x”$1)}’
/proc/2976/maps是进程2976内存映射表。内容可能如下:
00110000-00111000 r-xp 00110000 00:00 0 [vdso] 00111000-0011b000 r-xp 00000000 08:01 154857 /lib/libnss_files-2.8.so 0011b000-0011c000 r--p 0000a000 08:01 154857 /lib/libnss_files-2.8.so 0011c000-0011d000 rw-p 0000b000 08:01 154857 /lib/libnss_files-2.8.so 00907000-00923000 r-xp 00000000 08:01 157280 /lib/ld-2.8.so 00923000-00924000 r--p 0001c000 08:01 157280 /lib/ld-2.8.so 00924000-00925000 rw-p 0001d000 08:01 157280 /lib/ld-2.8.so 00927000-00a8a000 r-xp 00000000 08:01 157281 /lib/libc-2.8.so 00a8a000-00a8c000 r--p 00163000 08:01 157281 /lib/libc-2.8.so 00a8c000-00a8d000 rw-p 00165000 08:01 157281 /lib/libc-2.8.so 00a8d000-00a90000 rw-p 00a8d000 00:00 0 00abd000-00ac0000 r-xp 00000000 08:01 157284 /lib/libdl-2.8.so 00ac0000-00ac1000 r--p 00002000 08:01 157284 /lib/libdl-2.8.so 00ac1000-00ac2000 rw-p 00003000 08:01 157284 /lib/libdl-2.8.so 0383f000-03855000 r-xp 00000000 08:01 157307 /lib/libtinfo.so.5.6 03855000-03858000 rw-p 00015000 08:01 157307 /lib/libtinfo.so.5.6 08047000-080fa000 r-xp 00000000 08:01 1180910 /bin/bash 080fa000-080ff000 rw-p 000b3000 08:01 1180910 /bin/bash 080ff000-08104000 rw-p 080ff000 00:00 0 088bd000-088ff000 rw-p 088bd000 00:00 0 [heap] b7bfb000-b7bfd000 rw-p b7bfb000 00:00 0 b7bfd000-b7c04000 r--s 00000000 08:01 237138 /usr/lib/gconv/gconv-modules.cache b7c04000-b7d1e000 r--p 047d3000 08:01 237437 /usr/lib/locale/locale-archive b7d1e000-b7d5e000 r--p 0236e000 08:01 237437 /usr/lib/locale/locale-archive b7d5e000-b7f5e000 r--p 00000000 08:01 237437 /usr/lib/locale/locale-archive b7f5e000-b7f60000 rw-p b7f5e000 00:00 0 bfe5e000-bfe73000 rw-p bffeb000 00:00 0 [stack] 
   grep是过滤器:它从文件/proc/2976/maps里找到下面这行数据。
    bfe5e000-bfe73000 rw-p bffeb000 00:00 0 [stack]
   sed是过滤器:它把‘-’替换成‘ ’,数据变成下面的内容。
    bfe5e000 bfe73000 rw-p bffeb000 00:00 0 [stack]
   awk是过滤器:它计算0xbfe73000和0x bfe5e000差值,并打印出来。
19.在shell下面,一个新产生的进程可以通过用命令后面的符号“;”和“&”来分别以前台和后台的方式来执行,语法如下:
command
   产生一个前台的进程,下一个命令须等该命令运行结束后才能输入。
command &
   产生一个后台的进程,此进程在后台运行的同时,可以输入其他的命令。
20.shell函数详解;shell函数定义、参数传值、传参、返回值
   在shell中还可以定义函数。函数实际上也是由若干条shell命令组成的,因此它与shell程序形式上是相似的,不同的是它不是一个单独的进程,而是shell程序的一部分。函数定义的基本格式为:
functionname
{
    若干命令行
}

调用函数的格式为:
functionname param1 param2 ……

   shell函数可以完成某些例行的工作,而且还可以有自己的退出状态,因此函数也可以作为if、while等控制结构的条件。

   在函数定义时不用带参数说明,但在调用函数时可以带有参数,此时shell将把这些参数分别赋予相应的位置参数、、...及$*。

下面是一个名为xtitlebar的脚本,它可以改变终端窗口的名称。这里使用了一个名为help的函数,该函数在脚本中使用了两次:
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
   cat << HELP
   xtitlebar -- change the name of an xterm, gnome-terminal or kde konsole
   USAGE: xtitlebar [-h] "string_for_titelbar"
   OPTIONS: -h help text
   EXAMPLE: xtitlebar "cvs"
   HELP
   exit 0
}
# in case of error or if -h is given we call the function help:
[ -z "$1" ] && help
[ "$1" = "-h" ] && help
# send the escape sequence to change the xterm titelbar:
echo -e "33]0;$107"
#
在脚本中提供帮助是一种很好的编程习惯,可以方便其他用户(和自己)使用和理解脚本。

== 命令行参数 == XXXXXXXXXXXXXXXXXXXXXXXXXX
我们已经见过$* 和 $1, $2 ... $9 等特殊变量,这些特殊变量包含了用户从命令行输入的参数。迄今为止,我们仅仅了解了一些简单的命令行语法(比如一些强制性的参数和查看帮助的-h选项)。但是在编写更复杂的程序时,您可能会发现您需要更多的自定义的选项。通常的惯例是在所有可选的参数之前加一个减号,后面再加上参数值 (比如文件名)。

有好多方法可以实现对输入参数的分析,但是下面的使用case表达式的例子无疑是一个不错的方法。
#!/bin/sh
help()
{
   cat << HELP
   This is a generic command line parser demo.
   USAGE EXAMPLE: cmdparser -l hello -f -- -somefile1 somefile2
   HELP
   exit 0
}
 
while [ -n "$1" ]; do
case $1 in
   -h) help;shift 1;; # function help is called
   -f) opt_f=1;shift 1;; # variable opt_f is set
   -l) opt_l=$2;shift 2;; # -l takes an argument -> shift by 2
   --) shift;break;; # end of options
   -*) echo "error: no such option $1. -h for help";exit 1;;
   *) break;;
esac
done

echo "opt_f is $opt_f"
echo "opt_l is $opt_l"
echo "first arg is $1"
echo "2nd arg is $2"

你可以这样运行该脚本:
cmdparser -l hello -f -- -somefile1 somefile2

返回结果如下:
opt_f is 1
opt_l is hello
first arg is -somefile1
2nd arg is somefile2

这个脚本是如何工作的呢?脚本首先在所有输入命令行参数中进行循环,将输入参数与case表达式进行比较,如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例,首先输入的应该是包含减号的参数。
21.shell 命令分组的用法
在shell中有两种命令分组的方法:“()”和“{}”,前者当shell执行()中的命令时将再创建一个新的子进程,然后这个子进程去执行圆括弧中的命令。当用户在执行某个命令时不想让命令运行时对状态集合(如位置参数、环境变量、当前工作目录等)的改变影响到下面语句的执行时,就应该把这些命令放在圆括弧中,这样就能保证所有的改变只对子进程产生影响,而父进程不受任何干扰;{}用于将顺序执行的命令的输出结果用于另一个命令的输入(管道方式)。当我们要真正使用圆括弧和花括弧时(如计算表达式的优先级),则需要在其前面加上转义符(\)以便让shell知道它们不是用于命令执行的控制所用。
22.shell信号处理
  trap命令用于在shell程序中捕捉到信号,之后可以有三种反应方式:
(1)执行一段程序来处理这一信号
(2)接受信号的默认操作
(3)忽视这一信号

trap对上面三种方式提供了三种基本形式:
第一种形式的trap命令在shell接收到signal list清单中数值相同的信号时,将执行双引号中的命令串。
trap 'commands' signal-list
trap "commands" signal-list

为了恢复信号的默认操作,使用第二种形式的trap命令:
trap signal-list

第三种形式的trap命令允许忽视信号:
trap " " signal-list

注意事项: 
对信号11(段违例)不能捕捉,因为shell本身需要捕捉该信号去进行内存的转储。
在trap中可以定义对信号0的处理(实际上没有这个信号),shell程序在其终止(如执行exit语句)时发出该信号。
在捕捉到signal-list中指定的信号并执行完相应的命令之后,如果这些命令没有将shell程序终止的话,shell程序将继续执行收到信号时所执行的命令后面的命令,这样将很容易导致shell程序无法终止。

另外,在trap语句中,单引号和双引号是不同的,当shell程序第一次碰到trap语句时,将把commands中的命令扫描一遍。此时若commands是用单引号括起来的话,那么shell不会对commands中的变量和命令进行替换,否则commands中的变量和命令将用当时具体的值来替换。
23.shell脚本调试祥调
   在编程过程中难免会出错,有的时候,调试程序比编写程序花费的时间还要多,shell程序同样如此。

   shell程序的调试主要是利用bash命令解释程序的选择项。调用bash的形式是:
    bash -选择项 shell程序文件名

   几个常用的选择项是: 
   -e:如果一个命令失败就立即退出
   -n:读入命令但是不执行它们
   -u:置换时把未设置的变量看作出错
   -v:当读入shell输入行时把它们显示出来
   -x:执行命令时把命令和它们的参数显示出来

   上面的所有选项也可以在shell程序内部用“set -选择项”的形式引用,而“set +选择项”则将禁止该选择项起作用。如果只想对程序的某一部分使用某些选择项时,则可以将该部分用上面两个语句包围起来。
一、未置变量退出和立即退出
   未置变量退出特性允许用户对所有变量进行检查,如果引用了一个未赋值的变量就终止shell程序的执行。shell通常允许未置变量的使用,在这种情况下,变量的值为空。如果设置了未置变量退出选择项,则一旦使用了未置变量就显示错误信息,并终止程序的运行。未置变量退出选择项为“-u”。

   当shell运行时,若遇到不存在或不可执行的命令、重定向失败或命令非正常结束等情况时,如果未经重新定向,该出错信息会打印在终端屏幕上,而shell程序仍将继续执行。要想在错误发生时迫使shell程序立即结束,可以使用“-e”选项将shell程序的执行立即终止。
二、shell程序的跟踪
   调试shell程序的主要方法是利用shell命令解释程序的“-v”或“-x”选项来跟踪程序的执行。

   “-v”选择项使shell在执行程序的过程中,把它读入的每一个命令行都显示出来,而“-x”选择项使shell在执行程序的过程中把它执行的每一个命令在行首用一个“+”加上命令名显示出来。并把每一个变量和该变量所取的值也显示出来,因此,它们的主要区别在于:在执行命令行之前无“-v”则打印出命令行的原始内容,而有“-v”则打印出经过替换后的命令行的内容。

   除了使用shell的“-v”和“-x”选择项以外,还可以在shell程序内部采取一些辅助调试的措施。

   例如,可以在shell程序的一些关键地方使用echo命令把必要的信息显示出来,它的作用相当于C语言中的printf语句,这样就可以知道程序运行到什么地方及程序目前的状态。
24. # 注释
表示注释   #注释
在引号中间和\#等表示#本身
echo ${PATH#*:} # 参数替换,不是一个注释
echo $(( 2#101011 )) # 数制转换,不是一个注释
 
; 分隔
命令分隔,在一行中写多个命令  echo "aa" ; echo "bb"
在条件中的if和then如果放在同一行,也用;分隔
;; case条件的结束
 
. 命令相当于source命令
命令:source
文件名的前缀,隐藏文件
目录:.当前目录,..父目录
正则表达式:匹配任意单个字符
"" 部分引用 支持通配符扩展
 
'  ‘ 全引用,不进行通配符扩展
 
\ 转义
 
/ 目录分隔符
 
,  多个命令都被执行,但返回最后一个
 
` 后置引用
 
: 操作符
空操作
死循环:    while :
在if/then中表示什么都不做,引出分支
设置默认参数:   : ${username=`whoami`}
变量替换:    : ${HOSTNAME?} ${USER?} ${MAIL?}
在和 > (重定向操作符)结合使用时,把一个文件截断到0 长度,没有修改它的权限;如果文件在之前并不存在,那么就创建它.如:     
  : > data.xxx #文件"data.xxx"现在被清空了. 与 cat /dev/null >data.xxx 的作用相同 然而,这不会产生一个新的进程,因为":"是一个内建命令.
在和>>重定向操作符结合使用时,将不会对想要附加的文件产生任何影响.
如果文件不存在,将创建.
* 匹配0个或多个字符;数学乘法;**幂运算
 
? 匹配任意一个字符;但在((a>b?a:b))表示c语言中的三目运算
 

取变量的值 echo $PATH
正则表达式中表示行的结尾
${} 参数替换 ${PAHT}
$* 所有参数
$# 参数个数
$$ 进程的ID
$? 进程的返回状态
( )
命令组,在一个子Shell中运行   (a=3;echo $a) 其中定义的变量在后面不可用
数组初始化: array=(a,b,c)
{ } 代码块,即一个匿名函数,但其中定义的变量在后面依然可用
 
{ } \; 用在find的-exec中 $find -name *.txt -exec cat {} \;
 
[ ]
测试 [-z $1]
数组元素 a[1]='test'
[[]]表示测试 使用[[ ... ]]条件判断结构, 而不是[ ... ], 能够防止脚本中的许多逻辑错误. 比如, &&, ||, <, 和> 操作符能够正常存在于[[ ]]条件判断结构中, 但是如果出现在[ ]结构中的话, 会报错.
(( ))数学运算
在正则表达式中表示范围 [a-z]
< <<  >  重定向和进程替换  ls -al > a.txt
 
>  <  还用在ASCII比较 if [[ "$veg1" < "$veg2" ]]

\<,\> 正则表达式中的单词边界.如:bash$grep '\' textfile
 
| 管道
 
>| 强制重定向(即使设置了noclobber 选项--就是-C 选项).这将强制的覆盖一个现存文件.
 
|| 逻辑或操作 ;用在两个命令之间的时候,表示在前一个命令结束时,若返回值为 false,继续执行下一个命令
 
&& 逻辑与;用在两个命令之间的时候,表示在前一个命令结束时,若返回值为 true,继续执行下一个命令
 
& 后台运行
 
-
参数选项
减号
重定向stdin和stdout:cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
先前的工作目录 cd -
注:使用-开头的文件名和变量名可能会出现一些问题
+   一个命令或者过滤器的选项标记.
 
~ home目录
~+ 当前工作目录
~- 先前工作目录
 
^ 正则表达式中表示行首
 
$IFS 用来做一些输入命令的分隔符, 默认情况下是空白.
 
 
控制字符

修改终端或文本显示的行为. . 控制字符以CONTROL + key这种方式进行组合(同时按下). 控制字符也可以使用8进制或16进制表示法来进行表示, 但是前边必须要加上转义符.

控制字符在脚本中不能正常使用.

Ctl-B退格(非破坏性的), 就是退格但是不删掉前面的字符.

Ctl-C终结一个前台作业.

Ctl-D   从一个shell中登出(与exit很相像).
            "EOF"(文件结束). 这也能从stdin中终止输入.
            在console或者在xterm窗口中输入的时候, Ctl-D将删除光标下字符. 当没有字符时, Ctl-D将退出当前会话, 在一个xterm窗口中, 则会产生关闭此窗口的效果.

Ctl-G "哔" (beep). 在一些老式的打字机终端上, 它会响一下铃.

Ctl-H "退格"(破坏性的), 就是在退格之后, 还要删掉前边的字符.

Ctl-I 水平制表符.

Ctl-J 重起一行(换一行并到行首). 在脚本中, 也可以使用8进制表示法 -- '\012' 或者16进制表示法 -- '\x0a' 来表示.

Ctl-K垂直制表符.

Ctl-L 清屏(清除终端的屏幕显示). 在终端中, 与clear命令的效果相同. 当发送到打印机上时, Ctl-L会让打印机将打印纸卷到最后.

Ctl-M 回车.

Ctl-Q 恢复(XON).在一个终端中恢复stdin.

Ctl-S 挂起(XOFF).
         在一个终端中冻结stdin. (使用Ctl-Q可以恢复输入.)

Ctl-U 删除光标到行首的所有字符. 在某些设置下, 不管光标的所在位置Ctl-U都将删除整行输入.

Ctl-V当输入字符时, Ctl-V允许插入控制字符. 

Ctl-V主要用于文本编辑.

Ctl-W 
当在控制台或一个xterm窗口敲入文本时, Ctl-W将会删除当前光标到左边最近一个空格间的全部字符. 在某些设置下, Ctl-W将会删除当前光标到左边第一个非字母或数字之间的全部字符.
 

你可能感兴趣的:(linux,运维,服务器)