>

Bash 变量只有两种类型,字符串和数组。

变量的赋值与引用

变量通过等于号= (左右两边无空格)来赋值,通过 $ 来引用, 引用未定义过的变量,那么会以空字符取代。

数组变量的赋值:

  • Arr[index]=value
  • declare -a Arr
  • Arr=(value1 value2 … valueN) 注意:每个 value 以空格隔开
    e.g.
    ch=(1 2 3 4)
    echo “${ch[0]}”

注:数组下标的范围没有任何限制,同时也不必使用连续的分量.

关联数组:

  • declare -A Map

关联数组赋值:

Map=([x]=a, [y]=b)

往现有数组批量添加元素:

Arr+=(a b c)
Map+=([a]=1 [b]=2)

取值(引用)

${Arr[INDEX]}
${Map[KEY]}

${A[@]} 展开成所有的变量,而获取数组长度使用 ${#A[@]}

切片:

${ARY[@]:N:M}   注:N 是 offset,M 是 length

返回索引,相当于keys():

${!MAP[@]}

More examples:

declare -a Arr
declare -A Map
Map+=([a]=1 [b]=2)
Arr+=(a b c)

echo ${Arr[1]}
echo ${Map[a]}
echo "${Arr[@]}"
echo "${Map[@]}"
echo "${Arr[@]:0:1}"
echo "${!Map[@]}"

Arr[4]=a
echo ${Arr[@]}
echo ${Arr[3]}

与变量有关的内建命令(关键字)

(1) declare 和 typeset.两者具有一样的功能.其选项有:

[-/+]a 设置/撤消变量的数组属性
[-/+]i 设置/撤消变量的整数属性
[-/+]r 设置/撤消变量的只读属性
[-/+]x 设置/撤消变量的输出属性
-p var 显示变量属性

(2) export 和 local.

export 把变量输出到环境中,用法为:

export name
export name=value

export 的作用: 当Bash shell执行一个 程序时,将首先为该程序建立一个新的执行环境,称为子shell,
在Bash Shell中变量都是局部的,即它们只是在创建它们的子 Shell中是有意义的,使用export后,变量被设置为全局变量,这时可以被其它子Shell所识别

local 标记变量为局部的(如只能被函数内部使用),用法为:

local name
local name=value

(3) readonly.

指定变量为只读,执行后,改变量不能被再次赋值,用法为:

readonly name

位置变量 或 Shell 参数

Bash Shell 在解释用户命令时,会把命令行的第一元素(也即脚本或者命令本身)个作为 $0, 而其它字作为参数通过位置变量传递给程序.$1,…,$9分别代表第一,…,九个参数.
其中1-9是真正的参数名,”$”符只是用来标识变量的替换。

其它的还有:
$# 送给命令的参数个数
$@ 所有的参数,每个用双括号括起
$* 所有的参数作为一个整体,用双括号括起

(1) 与 Shell 自身有关的常用变量
LINENO 正在执行的命令在脚本中的行号
PWD 用户当前目录的全名
OLDPWD 最近一次执行cd之前,用户当前目录的全名
PPID 父进程ID
$ 当前进程ID
RANDOM 随机数(范围0-32767)
SECONDS Bash Shell的运行时间,单位是秒
REPLY select和read命令使用,以后会讲到
OPTARG
ORTIND 这两个变量由getopt命令设置
UID 当前用户的User ID
_ 上一条命令使用的最后一个参数

(2) 影响Shell行为的一些常用环境变量:

PATH 命令搜索路径,以冒号为分隔符.注意与DOS下不同的是, 当前目录不在系统路径里
HOME 用户home目录的路径名,是cd命令的默认参数
COLUMNS 定义了命令编辑模式下可使用命令行的长度
EDITOR 默认的行编辑器
VISUAL 默认的可视编辑器
FCEDIT 命令fc使用的编辑器
HISTFILE 命令历史文件
HISTSIZE 命令历史文件中最多可包含的命令条数
HISTFILESIZE 命令历史文件中包含的最大行数
IFS 定义SHELL使用的分隔符
LOGNAME 用户登录名
MAIL 指向一个需要SHELL监视其修改时间的文件.当该文件修改后, SHELL将发消息You hava mail给用户
MAILCHECK SHELL检查MAIL文件的周期,单位是秒
MAILPATH 功能与MAIL类似.但可以用一组文件,以冒号分隔,每个文件后 可跟一个问号和一条发向用户的消息
SHELL SHELL的路径名
TERM 终端类型
TMOUT SHELL自动退出的时间,单位为秒,若设为0则禁止SHELL自动退出
PROMPT_COMMAND 指定在主命令提示符前应执行的命令
PS1 主命令提示符
PS2 二级命令提示符,命令执行过程中要求输入数据时用
PS3 select的命令提示符
PS4 调试命令提示符
MANPATH 寻找手册页的路径,以冒号分隔
LD_LIBRARY_PATH 寻找库的路径,以冒号分隔

Bash中对变量的操作

Bash Shell可以进行变量的条件替换,即只有某种条件发生时才进行替换,替换条件放在{}中.
(1) ${value:-word}
当变量未定义或者值为空时,返回值为word的内容,否则返回变量的值.
(2) ${value:=word}
与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将 word赋值给value
(3) ${value:?message}
若变量已赋值的话,正常替换.否则将消息message送到标准错误输出(若此替换出现在Shell程序中,那么该程序将终止运行)

Bash中有一项特性,你可以方便地检查某个变量是否设置了,如果没有设置,就赋予一个默认值。尤其在处理环境变量的时候,这项特性会非常有用。
语法是 ${VAR:=VALUE}。此外,还有一个相似的语法,${VAR:=VALUE}和${VAR:=VALUE}。

下面展示下两者的区别

# expand to default variable
echo ${NULL-"Not null"} # Not null
echo ${NULL} #

# set default variable
echo ${NIL="Not nil"} # Not nil
echo ${NIL} # Not nil

最后介绍一个,当目标变量不存在时,指定报错信息的语法。

echo ${TARGET?Not Found} # 当$TARGET不存在时,显示TARGET: Not Found,并结束程序。

大小写变换

HI=HellO

echo "$HI" # HellO
echo ${HI^} # HellO
echo ${HI^^} # HELLO
echo ${HI,} # hellO
echo ${HI,,} # hello
echo ${HI~} # hellO
echo ${HI~~} #hELLo

^大写,,小写, ~大小写切换
重复一次只修改首字母,重复两次则应用于所有字母。

Advance Variable Operations

  1. Variable Extension (变量扩展)

基本形式:${var_name}
变量扩展含义:一种简易的条件判断,对不同的条件赋予变量不同的值替换.它和变量存在与否的关系很大.

1.1 测试变量是否存在的基本用法
语法: ${待测变量-默认值}
说明:若待测变量不存在则符合判断条件,以传回默认值作为处置.
解析:若待测变量不存在则返回默认值,否则返回变量的值

实例:

$ unset a
$ echo ${a-'default'}
default

1.2 测试变量不存在或其值为空时传回一个默认值
语法:${a:-default}
实例:

$ a=
$ echo ${a:-'default'}
default

1.3 测试变量不存在或其值为空给变量赋予一个默认值
语法:${待测变量:=默认值}
实例:

$ a=
$ echo ${a:='default'}
default
$ echo $a
default

1.4 测试变量不存在或其值为空,输出一个提示信息
语法:${待测变量:?提示信息}
实例:

$ a=
$ echo r={a:?Not Found}
Not Found

1.5 测试变量存在且为非空则返回真值
语法:${待测变量:+真值}
实例:

$ a=hello
$ echo ${a:+world}
world
总结:
符号 作用
判断变量是否为空,若为空则为真
  • 正向,判断变量是否存在且不为空,若存在且不为空则为真
  • 反向,判断变量是否不存在,若不存在则为空
    = 赋值,
    ? 提示信息

2.取字符串切片,获得字符串长度

2.1 取字符串切片
语法:
[1].${变量:开始的位置索引}
作用:截取从指定的位置开始到字符串结束的所有字符,开始字符的索引为0
实例:

$ str="hello world"
$ echo ${str:6}
world

[2].${变量:起始位置:长度}
作用:截取从指定的起始位置开始的指定长度的字符串。
实例:

$ str="hello world"
$ echo ${str:6:2}
wo

2.2 计算字符串长度
语法:${ #变量名称 }
实例:

$ str="hello world"
$ echo ${ #str }
11

3.对比样式
目的:截取变量值(字符串)的某一个部分
做法:将符合样式的部分字符串删除或替换

3.1 由字符串前面开始对比删除最短的相符者
语法:${待测变量#样式}
说明:从待测变量的值的左边开始对比,删除最短符合样式的字符串
实例:

$ filename="/usr/sbin/ntpdate"
$ echo ${filename#/*/}
sbin/ntpdate

3.2 由字符串前面开始对比删除最长的相符者
语法:${待测变量##样式}
实例:

$ filename="/usr/sbin/ntpdate"
$ echo ${filename##/*/}
ntpdate

3.3 由字符串后面开始对比删除最短的相符者
语法:${待测变量%样式}
实例:

$ filename="/usr/sbin/ntpdate"
$ echo ${filename%/*}
/usr/sbin

3.4 由字符串后面开始对比删除最长的相符者
语法:${待测变量%%样式}
实例:

$ filename="hello/usr/sbin/ntpdate"
$ echo ${filename%%/*}
hello

4.替换或删除部分字符串
4.1 只替换找到的第一个字符串
语法:${待测变量/样式/替换}
实例:

$ str="hello hello"
$ echo ${str/hello/world}
world hello

4.2 替换找到的所有样式字符串
语法:${待测变量//样式/替换}
实例:

$ str="hello hello"
$ echo ${str/hello/world}
world world

4.3 删除第一个指定的字符串
语法:${待测变量/要删除的字符串/}
实例:

$ str="hello hello"
$ echo ${str/hello/}
hello

4.4 删除所有指定的字符串
语法:${待测变量//要删除的变量/}
实例:

$ str="hello world hello"
$ echo ${str//hello/}
world

5.命令扩展
语法:$(命令)
实例: time=$(date) 等价 time=date

6.算术扩展
语法:$((算术))
实例:

$ echo "a=$((5*5))"
a=25

Reference
http://blog.chinaunix.net/uid-338594-id-2131863.html
http://blog.csdn.net/shallowgrave/article/details/12423239