Bash 一 ) 变量篇

变量的命名


第一个字符必须是下划线或者字母,后面的字符可以是数字、字母和下划线。变量的长度有限制,最多多少个不清楚,下面是一个长度为61的变量。

$ _123456789012345678901234567890123456789012345678901234567890=Happy 
$ echo $_123456789012345678901234567890123456789012345678901234567890 
Happy   
$ echo ${#_123456789012345678901234567890123456789012345678901234567890} 
61

正则表示: [[:alpha:]][[:alnum:]][[:alnum:]]...._

环境变量

符合POSIX Shell标准的环境变量,如PATHHOMEPWD等等变量

全局变量

程序传入的位置参数 $0-$9 -${10}-${19}...

  • $0: 程序或脚本的名称,比如在解释器里输入 if echo $0 | grep bash; then echo yes; fi 会得到 yes 的结果,如果使用 source (也就是.)或bash运行脚本, $0 会表示bash的名称,这往往不是我们想要的,因此建议先给脚本增加可执行权限(chmod u+x filename),然后运行脚本(./filename)。
  • $1-$9-${19}: 注意位置为两位数的位置参数引用时需要使用大括号。另外需要注意的是,大括号里引用其他变量的时候不能再使用$,需要改成感叹号。
  • $#: 位置参数的个数。
  • $?: 上一个命令的返回值,很少用。。。我一般都 command && { list } 或 ! command &&
  • 脚本中函数内的变量也算作是全局变量,不过需要运行函数后,里面的全局变量才开始生效。

局部变量

  • 在函数里使用local关键字的变量才被算作是局部变量。
  • 在函数里未使用local关键字的变量仍然是全局变量,在外部依然能被引用。
  • 如果你不习惯在函数里使用local关键字,那你在函数外部使用${var:-default}的时候就要小心了。

栗子

$ a=c b=a 
$ echo ${!b} 
c 
$ set param1 param2 param3 param4   # 重置位置参数
$ echo ${!#}                        # $#表示位置参数的个数,因为在大括号里,需要改成!#
param4
$ f(){
a=fuck
}
$ f
$ echo ${a:-you}
you

小练习:逆转字符串

rev_str(){
    # reverse string e.g rev_str new -> wen
    local old_str=$1 new_str

    while [ -n "old_str" ]; do
        new_str=${old_str:0:1}$new_str
        old_str=${old_str:1}
    done

    echo $new_str
}

变量默认值

  • ${var:-default}: 如果当前shell名空间没有var,或者var为空,那么var=default
  • ${var:+other}: 如果当前shell名空间有了var,且var不为空,那么var=other
  • 去冒号,去掉var为空或不为空的条件 e.g ${var-default} ${var+other}

栗子

$ rao=123 bing=fuck liang=666
$ echo ${rao:+xie}
xie
$ rao="" && echo ${rao:-xie}
xie

变量长度

  • ${#var}: 变量长度

荔枝

$ message="come back"                # 取最后一个字符 
$ echo ${message:$[${#message}-1]}   # $[]用来做int的算术运算
k

问题来了,那么怎么做小数的运算呢?这个一般也不会用到,但是以防一些恶劣的考官

#!/bin/bash
r=$(bc -q <<EOF      #标记开始  
    a=4
    b=3
    scale=4
    b/a
    quit
EOF                  #标记结束,记得不能缩进,也就是不能有空格        
    )

echo $r

变量下标切片

  • ${var:start:end}: 起始位置最小为0,结束位置最大为length-1,但是因为不包含end的原因,因此end要加1,在c语言中,每个字符串末尾都会添加\0表示字符串的结束,莫非。。。
  • ${var:start}: 截取从start到末尾的字符(包含start)
  • ${var::end}: 截取从第一个字符到end位置的字符(不包含end)

荔枝

$ rbl="welcome home"
$ echo ${rbl:3}, ${rbl::3}
come home, wel

变量匹配切片

  • ${var#pattern}非贪婪: 从开始向结尾进行匹配,去除第一个匹配到的字符串,留下剩下的。
  • ${var%pattern}非贪婪: 从末尾向开始进行匹配,去除第一个匹配到的字符串,留下剩下的。
  • ${var##pattern}贪婪: 从开始向结尾进行匹配,去除第MAX个匹配到的字符串,留下剩下的。(后面再也没有能与之匹配的字符串了)
  • ${var%%pattern}贪婪: 从末尾向开始进行匹配,去除第MAX个匹配到的字符串,留下剩下的。(后面再也没有能与之匹配的字符串了)
  • ${var//pattern/replace}

励志

$ file_path=/opt/install/apache-maven-1.8.4.tgz
$ echo ${file_path%/*}            # 文件所在路径
/opt/install
$ echo ${file_path##*/}           # 文件basename
apache-maven-1.8.4.tgz
$ echo ${file_path#${file_path%/*}/}
apache-maven-1.8.4.tgz
$ a=Home && printf "%s\n" $a ${a//H/h}    #这种情况使用tr更方便 e.g echo home | tr [:upper:] [:lower:]
Home
home

理智

#!/bin/bash
file_name=$(which $0)
path=${file_name%/*}
name=${file_name##*/}

echo the script\'s path: $path
echo the script\'s basename: $name
posted @ 2017-04-20 00:25  carryme15  阅读(156)  评论(0编辑  收藏  举报