天天看点

SHELL脚本-第二课回顾基础知识参考资料

SHELL脚本-第二课

  • 回顾
  • 基础知识
    • 特殊字符
  • 参考资料

回顾

  1. shell脚本编程的不适用场景的列举;1
  2. 简单的shell脚本展示;
  3. 解释器说明及注意事项;
  4. 脚本的运行方式。

基础知识

在此,我们将对一些特殊字符,变量命名及常见使用方式做一些介绍,以便你做基本的了解。首先,我们来看看看有哪些特殊的字符值得注意。

特殊字符

脚本中常常会出现一些特殊的字符,他们都表示一些特定的含义,我们接下来对它们做一一的介绍。

  1. #

    :以一个#开头的行 (#!是例外) 是注释行。例如:
  2. ;

    :【命令分割符】用分割符允许在同一行里有两个或更多的命令。例如:
    echo hello; echo there
    if [ -x "$filename" ]; then    # 注意:"if" and "then"需要分隔符
                                   # 思考一下这是为什么?
      echo "File $filename exists."; cp $filename $filename.bak
    else
      echo "File $filename not found."; touch $filename
    fi; echo "File test complete."
               
  3. ;;

    :case语句分支的结束符[双分号]。例如:
    case "$variable" in
    abc)  echo "\$variable = abc" ;;
    xyz)  echo "\$variable = xyz" ;;
    esac
               
  4. '

    :'STRING’能引用STRING里的所有字符(包括特殊字符也会被原样引用)。这是一个比使用双引号(“)更强的引用。 例如:
    #! /bin/bash
    hello="A B C D"
    echo $hello
    echo "$hello"
    echo '$hello'
               
    运行结果如下所示:

    $bash string

    A B C D

    A B C D

    $hello

    从运行结果可以看出,在单引号中的变量引用会被禁止,字符

    $

    会仅仅被认为是一个普通的字符,而不是变量的前缀。
  5. "

    :"STRING"的引用会使STRING里的特殊字符能够被解释。其中例子如上所示。
  6. .

    :等同于source。这是一个bash的内建命令。

    在这边

    .

    符号可以在脚本中的作用类似于

    C

    语言中的

    #include

    ,可以直接调用

    #include

    中的变量以及函数。调用

    ./bbb

    脚本如下:
    # This is a data file loaded by a script.
    # Files of this type may contain variables, functions, etc.
    # It may be loaded with a 'source' or '.' command by a shell script.
     
    # Let's initialize some variables.
     
    variable1=22
    variable2=474
    variable3=5
    variable4=97
    
    message1="Hello, how are you?"
    message2="Enough for now. Goodbye."
     
    print_message ()
    {
    	#Echoes any message passed to it.	 
    	if [ -z "$1" ]
    	then
    	    return 1
    	    # Error, if argument missing.
    	fi
    	
    	echo	 
    	until [ -z "$1" ]
    	do
    	   # Step through arguments passed to function.
    	   echo -n "$1"
    	   # Echo args one at a time, suppressing line feeds.
    	   echo -n " "
    	   # Insert spaces between words.
    	   shift
    	   # Next one.
    	done  
    	 
    	echo	 
    	return 0
    }  
               
    接下来,通过另外一个脚本调用其中的变量以及函数。例如:
    #!/bin/bash
    . bbb    # Load a data file.
    echo "variable1 (from data-file) = $variable1"
    echo "variable3 (from data-file) = $variable3"
    
    let "sum = $variable2 + $variable4"
    echo "Sum of variable2 + variable4 (from data-file) = $sum"
    echo "message1 (from data-file) is \"$message1\""
    exit 0
               
    运行结果如下所示:

    $ sh kkk

    variable1 (from data-file) = 22

    variable3 (from data-file) = 5

    Sum of variable2 + variable4 (from data-file) = 571

    message1 (from data-file) is “Hello, how are you?”

    -n This

    -n

    -n is

    -n

    -n the

    -n

    -n message-print

    -n

    -n function

    -n

    -n in

    -n

    -n the

    -n

    -n data-file.

    -n

  7. ,

    :逗号操作符用于连接一连串的数学表达式。这一串的数学表达式每一个都被求值,但只有最后一个被返回。例如:
  8. \

    :用于单个字符的引用机制。

    \X

    "转义"字符为

    X

  9. /

    :分隔一个文件路径的各个部分。例如:

    /home/bozo/projects/Makefile

  10. `:(由于这个符号比较特殊我就直接用这种方式表示了)将会重新分配一个命令甚至是多个命令的输出;它会将命令的输出如实地添加到另一个上下文中。例如:
    #!/bin/bash
    textfile_listing=`ls *`
    echo "$textfile_listing"
               
    运行结果如下所示(下面都是当前目录下的文件):

    $ sh commandchange

    bbb

    commandchange

    kkk

    string

  11. :

    :这个命令意思是空操作(即什么操作也不做). 它一般被认为是和shell的内建命令true是一样的。冒号":" 命令是Bash自身内建的, and its它的退出状态码是真(即0)。例如:
    if condition
    then :   # 什么也不做的分支
    else
       take-some-action
    fi
               

    :

    的特殊使用方法如下所示:
    #!/bin/bash
     # 用10种不同的方法计数到11.
     n=1; echo -n "$n "
     
     let "n = $n + 1"   # let "n = n + 1"也可以.
     echo -n "$n "
      
     :$((n = $n + 1))
     #  ":"是需要的,
     #+ 否则Bash会尝试把"$((n = $n + 1))"作为命令运行.
     echo -n "$n "
     
     (( n = n + 1 ))
     #  上面是更简单的可行的办法.
     echo -n "$n "
     
     n=$(($n + 1))
     echo -n "$n "
     
     : $[ n = $n + 1 ]
     #  ":"是需要的,
     #+ 否则Bash会尝试把"$[ n = $n + 1 ]"作为命令运行.
     #  即使"n"被当作字符串来初始化也能工作.
     echo -n "$n "
     
     n=$[ $n + 1 ]
     #  即使"n"被当作字符串来初始化也能工作.
     #* 应避免这种使用这种结构,因为它是被废弃并不可移植的.
     echo -n "$n "
     
     # 现在是C风格的增加操作.
     # 多谢Frank Wang指出这一点.
     
     let "n++"          # let "++n"也可以.
     echo -n "$n "
     
     (( n++ ))          # (( ++n )也可以.
     echo -n "$n "
     
     : $(( n++ ))       # : $(( ++n ))也可以.
     echo -n "$n "
     
     : $[ n++ ]         # : $[ ++n ]]也可以.
     echo -n "$n "
     echo
     
     exit 0
               
    运算结果如下所示:

    $ sh compoperater

    -n 1

    -n 2

    -n 3

    -n 4

    -n 5

    -n 6

    -n 7

    -n 8

    -n 9

    -n 10

    -n 11

  12. !

    :取反一个测试结果或退出状态。
  13. *

    :星号(*)字符在用于匹配文件名扩展的一个通配符,它自动匹配给定的目录下的每一个文件。 在计算时,星号

    *

    表示乘法运算符。两个星号

    **

    表示求幂运算符。
  14. ?

    :字符?被用于文件名扩展特性的文件名表达式的单字符匹配,同时也在扩展正则表达式中匹配任意一个字符。
  15. $

    :变量替换 (引用一个变量的内容)。
    var1=5
    var2=23skidoo
    
    echo $var1     # 5
    echo $var2     # 23skidoo
               
  16. &

    :在后台运行作业。 一个后面跟一个

    &

    的命令会在后台运行。
  17. |

    :管道。把上一个命令的输出传给下一个命令,或是shell。这是连接命令的一种方法。
  18. $?

    :保存退出码值的变量. 变量$?保存了一个命令,一个函数,或一个脚本的退出状态码的值。
  19. $*, $@

    :位置参数。
  20. ${}

    :参数替换。
  21. ()

    :命令组。一组由圆括号括起来的命令是新开一个子shell来执行的。因为是在子shell里执行,在圆括号里的变量不能被脚本的其他部分访问。因为父进程(即脚本进程)不能存取子进程(即子shell)创建的变量。例如:
    a=123
    ( a=321; )	       
    echo "a = $a"   # a = 123
    # 在圆括号里的变量"a"实际上是一个局部变量,作用局域只是在圆括号内用于数组始初化
               
  22. {}

    :这个结构也是一组命令代码块,事实上,它是匿名的函数。然而与一个函数所不同的,在代码块里的变量仍然能被脚本后面的代码访问。例如:
    1 #!/bin/bash
       2 # rpm-check.sh
       3 
       4 # 查询一个rpm安装包的描述,软件清单,和是否它能够被安装.
       5 # 并把结果保存到一个文件中.
       6 # 
       7 # 这个脚本使用一个代码块来举例说明。
       8 
       9 SUCCESS=0
      10 E_NOARGS=65
      11 
      12 if [ -z "$1" ]
      13 then
      14   echo "Usage: `basename $0` rpm-file"
      15   exit $E_NOARGS
      16 fi  
      17 
      18 { 
      19   echo
      20   echo "Archive Description:"
      21   rpm -qpi $1       # 查询软件包的描述.
      22   echo
      23   echo "Archive Listing:"
      24   rpm -qpl $1       # 查询软件包中的软件清单.
      25   echo
      26   rpm -i --test $1  # 查询该软件包能否被安装.
      27   if [ "$?" -eq $SUCCESS ]
      28   then
      29     echo "$1 can be installed."
      30   else
      31     echo "$1 cannot be installed."
      32   fi  
      33   echo
      34 } > "$1.test"       # 把代码块的所有输出重定向到一个文件中。
      35 
      36 echo "Results of rpm test in file $1.test"
      37 
      38 # 参考rpm的man手册来理解上面所用的选项。
      39 
      40 exit 0
               
  23. > &> >& >> <

    • sciptname >filename

      :重定向scriptname的输出到文件filename中去。如果文件filename存在则将会被覆盖。
    • command &>filename

      :会重定向命令command标准输出(stdout)和标准错误(stderr)到文件filename中。
    • command >&2

      :把命令command的标准输出(stdout)重定向到标准错误(stderr)。
    • scriptname >>filename

      :appends把脚本scriptname的输出追加到文件filename。如果filename不存在,则它会被创建。
  24. -

    :先前的工作目录。 命令

    cd -

    可以回到原来的工作目录.它使用了

    $OLDPWD

    环境变量。
  25. ~+

    :当前工作目录。它与外部变量

    $PWD

    是一致的。
  26. ~-

    :先前的工作目录。它与外部变量

    $OLDPWD

    是一致的。

以上即为常见的特殊字符,可更有利于运用特殊字符来简化脚本编程。

参考资料

  1. SHELL脚本-第一课 ↩︎