zoukankan      html  css  js  c++  java
  • 参数展开与特殊字符

    ${var:-word},var存在且非null,则返回其值,否则返回word。即变量未定义返回默认值。

    ${var:=word},var存在且非null,则返回其值,否则将var设置为word并返回word。即变量未定义测设为默认值。

    ${var:?errormsg},var存在且非null,则返回其值,否则显示var:errormsg错误信息,并退出当前命令或脚本。

    ${var:+word},var存在且非null,则返回word,否则返回null。

    每个运算符内的冒号:都是可选的,如果省略则每个定义中的"存在且非null"改为"存在".

    username2 = ${username2:-`whoami`}
    DEFAULT_FILENAME=generic.data
    filename=${1:-$DEFAULT_FILENAME}
    dummy_variable=${ZZXy23AB?"ZXy23AB has not been set."}
    a=${param4:+xyz}

    模式匹配:假设path=/home/tolstoy/mem/long.file.name

    ${var#pattern},如果模式匹配变量的开头处,则删除匹配的最短部分并返回剩下的部分。

    ${var##pattern},如果模式匹配变量的开头处,则删除匹配的最长部分并返回剩下的部分。

    ${var%pattern},如果模式匹配变量的结尾处,则删除匹配的最短部分并返回剩下的部分。

    ${var%%pattern},如果模式匹配变量的结尾处,则删除匹配的最长部分并返回剩下的部分。

    例:

    ${path#/*/}结果为toltoy/mem/long.file.name

    ${path##/*/}结果为long.file.name  一个"#"表示匹配最短, "##"表示匹配最长

    ${path%.*}结果为/home/toltoy/mem/long.file

    ${path%%.*}结果为/home/toltoy/mem/long  一个"%"表示匹配最短, "%%"表示匹配最长.

    return=${1#0} # "1"表示的是"$1" -- 传递进来的参数. "0"就是我们想从"$1"中删除的子串-- 去掉零.

     变量长度/子串删除

    ${#var}
    字符串长度(变量$var得字符个数). 对于array来说, ${#array}表示的是数组中第一个元素的长度.

    例外情况:

    ${#*}和${#@}表示位置参数的个数.
    对于数组来说, ${#array[*]}和${#array[@]}表示数组中元素的个数.

    变量扩展/子串替换
    ${var:pos}   变量var从位置pos开始扩展(也就是pos之前的字符都丢弃).
    ${var:pos:len} 变量var从位置pos开始, 并扩展len个字符.
    ${var/Pattern/Replacement} 使用Replacement来替换变量var中第一个匹配Pattern的字符串. 如果省略Replacement, 那么第一个匹配Pattern的字符串将被替换为空, 也就是被删除了.
    ${var//Pattern/Replacement} 全局替换. 所有在变量var匹配Pattern的字符串, 都会被替换为Replacement.和上边一样, 如果省略Replacement, 那么所有匹配Pattern的字符串, 都将被替换为空, 也就是被删除掉.

    ${var/#Pattern/Replacement} 如果变量var的前缀匹配Pattern, 那么就使用Replacement来替换匹配到Pattern的字符串.
    ${var/%Pattern/Replacement} 如果变量var的后缀匹配Pattern, 那么就使用Replacement来替换匹配到Pattern的字符串.

    ${!varprefix*}, ${!varprefix@} 匹配所有之前声明过的, 并且以varprefix开头的变量.

    xyz23=whatever     xyz24=

    a=${!xyz*} # 展开所有以"xyz"开头的, 并且之前声明过的变量名.         echo "a = $a" # a = xyz23 xyz24

    a=${!xyz@} # 同上.    echo "a = $a" # a = xyz23 xyz24

    shell变量$#,$@,$0,$1,$2的含义解释: 

    变量说明: 
    $$ Shell本身的PID(ProcessID) 
    $! :Shell最后运行的后台Process的PID 
    $? :最后运行的命令的结束代码(返回值) 
    $- :使用Set命令设定的Flag一览 
    $* :所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 
    $@ :所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 
    $# :添加到Shell的参数个数 
    $0 :Shell本身的文件名 
    $1~$n :添加到Shell的各参数值。$1是第1参数、$2是第2参数…。 

    $@与$*中的参数只有在被双引号引用起来的时候才会不同.

    $? : 命令, 函数, 或者是脚本本身的(参见例子 23-7)退出状态码

    分号;可以在同一行写两个语句,"if"和"then"也需要分隔。

    终止case选项[双分号, 即;;].

    冒号的作用:

    1. 空命令,等价于“NOP”,也可被认为与shell的内建命令true的作用相同 ":"命令是一个bash的内建命令, 它的退出码(exit

    status)是"true"(0).

    2. 死循环:

    while :
    do
       operation-1
       operation-2
       ...
       operation-n
    done
    
    # Same as:
    #    while true
    #    do
    #      ...
    #    done

    3.在if/then中的占位符:

    if condition
    then :   # Do nothing and branch ahead
    else     # Or else ...
       take-some-action
    fi

    4.在一个二元命令中提供一个占位符

    : ${username=`whoami`}
    # ${username=`whoami`}   Gives an error without the leading :
    #                        unless "username" is a command or builtin...
    
    : ${1?"Usage: $0 ARGUMENT"}     # From "usage-message.sh example script.

    5.使用参数替换来评估字符串变量

    : ${HOSTNAME?} ${USER?} ${MAIL?}

    6.在与>重定向操作符结合使用时, 将会把一个文件清空, 但是并不会修改这个文件的权限. 如果之

    前这个文件并不存在, 那么就创建这个文件.

    : > data.xxx   # File "data.xxx" now empty.	      
    
    # Same effect as   cat /dev/null >data.xxx
    # However, this does not fork a new process, since ":" is a builtin.

     在与>>重定向操作符结合使用时, 将不会对预先存在的目标文件(: >> target_file)产生任何影

    响. 如果这个文件之前并不存在, 那么就创建它.

     7. ":"还用来在/etc/passwd和$PATH变量中做分隔符.

    bash$ echo $PATH
    /usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games

     *的作用:通配符[星号, 即*]. *可以用来做文件名匹配的"通配符".含义是, 可以用来匹配给定目录下的任何文件名.   *也可以用在正则表达式中, 用来匹配任意个数(包含0个)的字符.

    ?:通配符. ?在通配中, 用来做匹配单个字符的"通配符", 在正则表达式中, 也是用来表示一个字符.

    ():命令组,在括号中的命令列表, 将会作为一个子shell来运行.在括号中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的.父进程, 也就是脚本本身, 将不能够读取在子进程中创建的变量, 也就是在子shell中创建的变量.

    初始化数组.  Array=(element1 element2 element3)

    {}

    大括号扩展.   cat {file1,file2,file3} > combined_file   # 把file1, file2, file3连接在一起, 并且重定向到combined_file中.
    cp file22.{txt,backup}  # 拷贝"file22.txt"到"file22.backup"中

    代码块[大括号, 即{}]. 又被称为内部组, 这个结构事实上创建了一个匿名函数(一个没有名字的函数). 然而, 与"标准"函数不同的是, 在其中声明的变量,对于脚本其他部分的代码来说还是可见的.

     例子 3-1. 代码块和I/O重定向

    #!/bin/bash
    # Reading lines in /etc/fstab.
    
    File=/etc/fstab
    
    {
    read line1
    read line2
    } < $File
    
    echo "First line in $File is:"
    echo "$line1"
    echo
    echo "Second line in $File is:"
    echo "$line2"
    
    exit 0
    例子 3-2. 将一个代码块的结果保存到文件
    #!/bin/bash
    # rpm-check.sh
    
    #  Queries an rpm file for description, listing,
    #+ and whether it can be installed.
    #  Saves output to a file.
    # 
    #  This script illustrates using a code block.
    
    SUCCESS=0
    E_NOARGS=65
    
    if [ -z "$1" ]
    then
      echo "Usage: `basename $0` rpm-file"
      exit $E_NOARGS
    fi  
    
    { # Begin code block.
      echo
      echo "Archive Description:"
      rpm -qpi $1       # Query description.
      echo
      echo "Archive Listing:"
      rpm -qpl $1       # Query listing.
      echo
      rpm -i --test $1  # Query whether rpm file can be installed.
      if [ "$?" -eq $SUCCESS ]
      then
        echo "$1 can be installed."
      else
        echo "$1 cannot be installed."
      fi  
      echo              # End code block.
    } > "$1.test"       # Redirects output of everything in block to file.
    
    echo "Results of rpm test in file $1.test"
    
    # See rpm man page for explanation of options.
    
    exit 0
     与上面所讲到的()中的命令组不同的是, {大括号}中的代码块将不会开启一

    个新的子shell.

     > &> >& >> < <> 重定向.

    scriptname >filename 重定向scriptname的输出到文件filename中. 如果filename存在的话, 那么将会被覆盖.
    command &>filename 重定向command的stdout和stderr到filename中.
    command >&2 重定向command的stdout到stderr中.
    scriptname >>filename 把scriptname的输出追加到文件filename中. 如果filename不存在的话,将会被创建.

    [[ ]]测试Test expression between [[ ]]. More flexible than the single-bracket [ ] test, this is a shell keyword.

    进程替换.(command)>   ,  <(command)

    <, >正则表达式中的单词边界 . bash$ grep '<the>' textfile

    |  管道. 分析前边命令的输出, 并将输出作为后边命令的输入. 这是一种产生命令链的好方法.cat $filename1 $filename2 | grep $search_word

    >|强制重定向(即使设置了noclobber选项 -- 就是-C选项). 这将强制的覆盖一个现存文件.

    || 或-逻辑操作. 在一个条件测试结构中, 如果条件测试结构两边中的任意一边结果为true的话,||操作就会返回0(代表执行成功).

    & 后台运行命令. 一个命令后边跟一个& 表示在后台运行.  在一个脚本中,命令和循环都可能运行在后台.

    &&  与-逻辑操作. 在一个条件测试结构中, 只有在条件测试结构的两边结果都为true的时候, &&操作才会返回0(代表sucess).

    - 用于重定向stdin或stdout[破折号, 即-].

    (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
    # Move entire file tree from one directory to another
    # [courtesy Alan Cox <a.cox@swansea.ac.uk>, with a minor change]
    
    # 1) cd /source/directory
    #    Source directory, where the files to be moved are.
    # 2) &&
    #   "And-list": if the 'cd' operation successful,
    #    then execute the next command.
    # 3) tar cf - .
    #    The 'c' option 'tar' archiving command creates a new archive,
    #    the 'f' (file) option, followed by '-' designates the target file
    #    as stdout, and do it in current directory tree ('.').
    # 4) |
    #    Piped to ...
    # 5) ( ... )
    #    a subshell
    # 6) cd /dest/directory
    #    Change to the destination directory.
    # 7) &&
    #   "And-list", as above
    # 8) tar xpvf -
    #    Unarchive ('x'), preserve ownership and file permissions ('p'),
    #    and send verbose messages to stdout ('v'),
    #    reading data from stdin ('f' followed by '-').
    #
    #    Note that 'x' is a command, and 'p', 'v', 'f' are options.
    #
    # Whew!
    
    
    
    # More elegant than, but equivalent to:
    #   cd source/directory
    #   tar cf - . | (cd ../dest/directory; tar xpvf -)
    #
    #     Also having same effect:
    # cp -a /source/directory/* /dest/directory
    #     Or:
    # cp -a /source/directory/* /source/directory/.[^.]* /dest/directory
    #     If there are hidden files in /source/directory.
    bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf -
    #  --uncompress tar file--      | --then pass it to "tar"--
    #  If "tar" has not been patched to handle "bunzip2",
    #+ this needs to be done in two discrete steps, using a pipe.
    #  The purpose of the exercise is to unarchive "bzipped" kernel source.

    例子 3-4 备份最后一天所有修改的文件

    #!/bin/bash
    
    #  Backs up all files in current directory modified within last 24 hours
    #+ in a "tarball" (tarred and gzipped file).
    
    BACKUPFILE=backup-$(date +%m-%d-%Y)
    #                 Embeds date in backup filename.
    #                 Thanks, Joshua Tschida, for the idea.
    archive=${1:-$BACKUPFILE}
    #  If no backup-archive filename specified on command-line,
    #+ it will default to "backup-MM-DD-YYYY.tar.gz."
    
    tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
    gzip $archive.tar
    echo "Directory $PWD backed up in archive file "$archive.tar.gz"."
    
    
    #  Stephane Chazelas points out that the above code will fail
    #+ if there are too many files found
    #+ or if any filenames contain blank characters.
    
    # He suggests the following alternatives:
    # -------------------------------------------------------------------
    #   find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
    #      using the GNU version of "find".
    
    
    #   find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' ;
    #         portable to other UNIX flavors, but much slower.
    # -------------------------------------------------------------------
    
    
    exit 0
     -  先前的工作目录. cd -将会回到先前的工作目录.
    + 某些命令内建命令使用+来打开特定的选项, 用-来禁用这些特定的选项.

    ~+ 当前工作目录. 相当于$PWD内部变量.

    ~-先前的工作目录. 相当于$OLDPWD内部变量.

     

    使用双引号还能够阻止单词分割(word splitting). [3]如果一个参数被双引号扩起来的话, 那么这个参数将认为是一个单元, 即使这个参数包含有空白, 那里面的单词也不会被分隔开.
     variable1="a variable containing five words"
    COMMAND This is $variable1 # 用下面7个参数执行COMMAND命令:
     # "This" "is" "a" "variable" "containing" "five" "words"

    COMMAND "This is $variable1" # 用下面1个参数执行COMMAND命令:
    # "This is a variable containing five words"


    variable2="" # Empty.

    COMMAND $variable2 $variable2 $variable2 # COMMAND将不带参数执行.
    COMMAND "$variable2" "$variable2" "$variable2" # COMMAND将以3个空参数来执行.
    COMMAND "$variable2 $variable2 $variable2" # COMMAND将以1个参数来执行(2空格).

    在echo语句中, 只有在单词分割(word splitting)或者需要保留空白的时候, 才需要把参数用双引号括起来.

  • 相关阅读:
    November 07th, 2017 Week 45th Tuesday
    November 06th, 2017 Week 45th Monday
    November 05th, 2017 Week 45th Sunday
    November 04th, 2017 Week 44th Saturday
    November 03rd, 2017 Week 44th Friday
    Asp.net core 学习笔记 ( Area and Feature folder structure 文件结构 )
    图片方向 image orientation Exif
    Asp.net core 学习笔记 ( Router 路由 )
    Asp.net core 学习笔记 ( Configuration 配置 )
    qrcode render 二维码扫描读取
  • 原文地址:https://www.cnblogs.com/fly-xiang-zhao/p/3675575.html
Copyright © 2011-2022 走看看