定义变量时,变量名不加美圆符号($,PHP语言中变量须要),如:shell
your_name="runoob.com"
注意,变量名和等号之间不能有空格,这可能和你熟悉的全部编程语言都不同。同时,变量名的命名须遵循以下规则:编程
有效的 Shell 变量名示例以下:数组
DEVICENAME
LD_LIBRARY_PATH
_var
var2
无效的变量命名:bash
?devicetype=123 user name=runoob
status = 0
7isactive=1
除了显式地直接赋值,还能够用语句给变量赋值,如:服务器
for file in `ls /etc` 或 for file in $(ls /etc)
以上语句将 /etc 下目录的文件名循环出来。编程语言
使用一个定义过的变量,只要在变量名前面加美圆符号便可,如:函数
#!/bin/bash devicetype='lift' echo $devicetype
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,好比下面这种状况:post
for skill in Ada Coffe Action Java; do echo "I am good at ${skill}Script" done
若是不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是咱们指望的样子了。this
推荐给全部变量加上花括号,这是个好的编程习惯。url
已定义的变量,能够被从新定义,如:
#!/bin/bash devicetype='lift' echo $devicetype devicetype='crane' echo $devicetype
结果
lift
crane
这样写是合法的,但注意,第二次赋值的时候不能写$your_name="alibaba",使用变量的时候才加美圆符($)。
使用 readonly 命令能够将变量定义为只读变量,只读变量的值不能被改变。
下面的例子尝试更改只读变量,结果报错:
#!/bin/bash pdfurl='http://www.xxxx.com/resource/pdfs/181101/6238258284.pdf' echo $pdfurl readonly pdfurl pdfurl='http://www.xxxx.com/resource/pdfs/181111/6238258255.pdf' echo $pdfurl
运行脚本,能够看到第二次赋值没有成功,而且报错,结果以下:
http://www.xxxx.com/resource/pdfs/181101/6238258284.pdf http://www.xxxx.com/resource/pdfs/181101/6238258284.pdf /tmp/922461712/main.sh: line 5: pdfurl: readonly variable
使用 unset 命令能够删除变量。语法:
unset variable_name
变量被删除后不能再次使用。unset 命令不能删除只读变量。
实例
#!/bin/bash # 定义两个变量并打印 pdfurl='http://www.xxxx.com/resource/pdfs/181101/6238258284.pdf' imgurl='http://www.xxxx.com/resource/imgs/181101/6238258284.jpg' echo $pdfurl echo $imgurl # 将pdfurl置为只读 readonly pdfurl # 尝试删除这两个变量 unset pdfurl unset imgurl # 再次打印 echo $pdfurl echo $imgurl
执行实例,能够看到第二次只打印了imgurl。
http://www.xxxx.com/resource/pdfs/181101/6238258284.pdf http://www.xxxx.com/resource/imgs/181101/6238258284.jpg http://www.xxxx.com/resource/pdfs/181101/6238258284.pdf /tmp/219033109/main.sh: line 10: unset: pdfurl: cannot unset: readonly variable
Shell变量的做用域(Scope),就是 Shell 变量的有效范围(可使用的范围)。
在不一样的做用域中,同名的变量不会相互干涉,就好像 A 班有个叫小明的同窗,B 班也有个叫小明的同窗,虽然他们都叫小明(对应于变量名),可是因为所在的班级(对应于做用域)不一样,因此不会形成混乱。可是若是同一个班级中有两个叫小明的同窗,就必须用相似于“大小明”、“小小明”这样的命名来区分他们。
Shell 变量的做用域能够分为三种:
所谓全局变量,就是指变量在当前的整个 Shell 会话中都有效。每一个 Shell 会话都有本身的做用域,彼此之间互不影响。在 Shell 中定义的变量,默认就是全局变量。
想要实际演示全局变量在不一样 Shell 会话中的互不相关性,可在图形界面下同时打开两个 Shell,或使用两个终端远程链接到服务器(SSH)。
首先打开一个 Shell 窗口,定义一个变量 a 并赋值为 1,而后打印,这时在同一个 Shell 窗口中是可正确打印变量 a 的值的。而后再打开一个新的 Shell 窗口,一样打印变量 a 的值,但结果却为空,如图 所示。
这说明全局变量 a 仅仅在定义它的第一个 Shell 中有效,对其它 Shell 没有影响。这很好理解,就像小王家和小徐家都有一部电视机(变量名相同),可是同一时刻小王家和小徐家的电视中播放的节目能够是不一样的(变量值不一样)。
须要强调的是,全局变量的做用范围是当前的 Shell 会话,而不是当前的 Shell 脚本文件,它们是不一样的概念。打开一个 Shell 窗口就建立了一个 Shell 会话,打开多个 Shell 窗口就建立了多个 Shell 会话,每一个 Shell 会话都是独立的进程,拥有不一样的进程 ID。在一个 Shell 会话中,能够执行多个 Shell 脚本文件,此时全局变量在这些脚本文件中都有效。
例如,如今有两个 Shell 脚本文件,分别是 a.sh 和 b.sh。a.sh 的代码以下:
#!/bin/bash echo $a b=200
b.sh 的代码以下:
#!/bin/bash echo $b
打开一个 Shell 窗口,输入如下命令:
$ a=99 $ . ./a.sh 99 $ . b.sh 200 $
从输出结果能够发现,在 Shell 会话中以命令行的形式定义的变量 a,在 a.sh 中有效;在 a.sh 中定义的变量 b,在 b.sh 中也有效。
Shell 也支持自定义函数,可是 Shell 函数和 C/C++、Java 等其余编程语言函数的一个不一样点就是:在 Shell 函数中定义的变量默认也是全局变量,它和在函数外部定义变量拥有同样的效果。请看下面的代码:
#!/bin/bash #定义函数 function func(){ a=99 } #调用函数 func #输出函数内部的变量 echo $a
输出结果:
99
a 是在函数内部定义的,可是在函数外部也能够获得它的值,证实它的做用域是全局的,而不是仅限于函数内部。
要想变量的做用域仅限于函数内部,那么能够在定义时加上命令,此时该变量就成了局部变量。请看下面的代码:local
#!/bin/bash #定义函数 function func(){ local a=99 } #调用函数 func #输出函数内部的变量 echo $a
输出结果为空,代表变量 a 在函数外部无效,是一个局部变量。
Shell 变量的这个特性和 JavaScript 中的变量是相似的。在 JavaScript 函数内部定义的变量,默认也是全局变量,只有加上关键字,它才会变成局部变量。var
全局变量只在当前 Shell 会话中有效,若是使用命令将它导出,那么它就在全部的子 Shell 中也有效了,这称为“环境变量”。
环境变量被建立时所处的 Shell 被称为父 Shell,若是在父 Shell 中再建立一个 Shell,则该 Shell 被称做子 Shell。当子 Shell 产生时,它会继承父 Shell 的环境变量为本身所用,因此说环境变量可从父 Shell 传给子 Shell。不难理解,环境变量还能够传递给孙 Shell。export
注意,环境变量只能向下传递而不能向上传递,即“传子不传父”。
在一个 Shell 中建立子 Shell 最简单的方式是运行 bash 命令,如图所示。
经过命令能够一层一层地退出 Shell。
下面演示一下环境变量的使用:exit
$ a=22 #定义一个全局变量 $ echo $a #在当前Shell中输出a,成功 22 $ bash #进入子Shell $ echo $a #在子Shell中输出a,失败 $ exit #退出子Shell exit $ export a #将a导出为环境变量 $ bash #从新进入子Shell $ echo $a #在子Shell中再次输出a,成功 22 $ exit #退出子Shell exit $ exit #退出父Shell,结束整个Shell会话
能够发现,默认状况下,a 在子 Shell 中是无效的;使用 export 将 a 导出为环境变量后,在子 Shell 中就可使用了。
这种形式是在定义变量 a 之后再将它导出为环境变量,若是想在定义的同时导出为环境变量,能够写做。
注意,本节咱们一直强调的是环境变量在子 Shell 中有效,并无说它在全部的 Shell 种有效;若是你经过终端建立一个新的 Shell,那么它就不是当前 Shell 的子 Shell,环境变量对这个 Shell 就是无效的。
此外,经过命令导出的环境变量是临时的,关闭 Shell 会话后它就销毁了。因此,这种环境变量也只是在局部范围内起做用,并不影响全部 Shell。
若是想让环境变量在全部 Shell 中都有效,而且可以永久保存,在关闭 Shell 后也不丢失,那么就须要把环境变量写入启动文件。至于如何写入文件,请你们自行百度,这里就再也不赘述了。
export aexport a=22export
字符串是shell编程中最经常使用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串能够用单引号,也能够用双引号,也能够不用引号。单双引号的区别跟PHP相似。
str='this is a string'
单引号字符串的限制:
#!/bin/bash ordernum='32782974960173' # 双引号里既能够有变量又能够有转义 orderdetail="this is the order $ordernum detail info, find it by \\" echo $ordernum echo $orderdetail
输出结果为:
32782974960173 this is the order 32782974960173 detail info, find it by \
双引号的优势:
#!/bin/bash datestr='2018-01-01' timestr='11:11:11' # 双引号拼接 echo '双引号拼接字符串' currentdatetime_1="now time is "$datestr" "$timestr" !" currentdatetime_2="now time is ${datestr}+${timestr} 。" echo $currentdatetime_1 $currentdatetime_2 # 单引号拼接 echo '单引号拼接字符串' currentdatetime_11='now time is '$datestr' '$timestr' !' currentdatetime_22='now time is ${datestr}+${timestr} 。' echo $currentdatetime_11 $currentdatetime_22
输出结果为:
双引号拼接字符串 now time is 2018-01-01 11:11:11 ! now time is 2018-01-01+11:11:11 。 单引号拼接字符串 now time is 2018-01-01 11:11:11 ! now time is ${datestr}+${timestr} 。
#!/bin/bash datestr='2018-01-01' echo $datestr 的长度为: ${#datestr}
结果
2018-01-01 的长度为: 10
如下实例从字符串第 1 个字符开始截取 4 个字符:
#!/bin/bash datestr='2018-01-02' echo 日期【 $datestr 】的年为: ${datestr:0:4}
结果
日期【 2018-01-02 】的年为: 2018
查找字符 - 或 : 的位置(哪一个先出现就计算哪一个):
#!/bin/bash datestr='2018-01-02 11:11:11' echo `expr index "$datestr" -:`
结果:
5
注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。
bash支持一维数组(不支持多维数组),而且没有限定数组的大小。
相似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标能够是整数或算术表达式,其值应大于或等于 0。
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的通常形式为:
数组名=(值1 值2 ... 值n)
例如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
还能够单独定义数组的各个份量:
array_name[0]=value0 array_name[1]=value1 array_name[n]=valuen
能够不使用连续的下标,并且下标的范围没有限制。
读取数组元素值的通常格式是:
${数组名[下标]}
例如:
valuen=${array_name[n]}
使用 @ 符号能够获取数组中的全部元素,例如:
echo ${array_name[@]}
获取数组长度的方法与获取字符串长度的方法相同,例如:
# 取得数组元素的个数 length=${#array_name[@]} # 或者 length=${#array_name[*]} # 取得数组单个元素的长度 lengthn=${#array_name[n]}
以 # 开头的行就是注释,会被解释器忽略。
经过每一行加一个 # 号设置多行注释,像这样:
#-------------------------------------------- # 这是一个注释 # author:菜鸟教程 # site:www.runoob.com # slogan:学的不只是技术,更是梦想! #-------------------------------------------- ##### 用户配置区 开始 ##### # # # 这里能够添加脚本描述信息 # # ##### 用户配置区 结束 #####
若是在开发过程当中,遇到大段的代码须要临时注释起来,过一下子又取消注释,怎么办呢?
每一行加个#符号太费力了,能够把这一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释同样的效果。
多行注释还可使用如下格式:
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
EOF 也可使用其余符号:
:<<' 注释内容... 注释内容... 注释内容... ' :<<! 注释内容... 注释内容... 注释内容... !