More Related Content Similar to 2, bash synax simplified (20) 2, bash synax simplified3. 概述
• 每一门编程语言都有其各自的语法结构和
代码风格, bash脚本语言也不例外. 这一章简
要描述bash的语法结构, 包括:
1, 变量 2, 数组 3, 脚本参数
4, 运算符 5, 条件判断 6, 循环
7, 命令替换 8, 算术运算 9, Globbing
10, 函数
4. shebang 和 注释
• shebang行指的是脚本文件的第一行, 用于指定执行
脚本的shell类型, bash脚本的第一行是: #!/bin/bash.
可以指定shell执行的选项, 常用的有-x选项, 用于打
印执行了哪些命令, 而不仅仅是结果;
• shell通常使用#标识注释单行, 示例:
其实shell也可以做到多行注释, 但不常用. 用法如下:
:<<BLOCK
...
segment
...
BLOCK
5. 变量
• 变量分为:
1, 环境变量
又称为全局变量(global variable), 使用export或者
declare -x命令创建, 示例:
export VAR=“abc”
declare -x VAR=“abc”
2, 局部变量
与全局变量不同的是, 局部变量(local variable)的作用域
仅限定在当前的shell脚本中, 不能够被子shell继承. 使
用直接赋值方式创建局部变量:
variable_name=“var”;
或者使用declare命令:
declare variable_name=“var”;
两者的区别在于, declare命令创建的变量仅存在于当前的作用域,
比如在函数中使用declare创建的变量尽在该函数中有效; 而直接赋值的方
式则在当前shell环境或者脚本范围内有效, 示例: demo1.sh.
6. declare
• declare是bash内置的一个命令, 用于声明变量, 该命
令有如下选项:
-r 声明一个只读变量, 等同于readonly内置命令;
-i 声明一个整数变量; 示例:
declare -i i=5
i=i+1
echo $i # output 6
-a 声明一个数组;
-x 声明一个环境变量, 等同于export;
-f 此选项不带参数, 列出当前创建的所有函数.
示例: demo2.sh
7. echo
• echo是bash的一个内置命令, 用于打印. 示例:
echo “Hello world” # 打印Hello World
常用选项如下:
-n 打印后不换行
-e 对字符进行转义, 示例:
echo -e “hit man” # t输出为tab符
• echo命令可用于打印变量的值, 使用${varname} 或者
$varname提取变量的值;
• echo参数可以使用双引号或者单引号, 如果是双引号
则会对$varname进行替换, 单引号则原样输出.
• 示例: demo3.sh
8. 数组
• bash使用declare -a命令创建数组变量, 示例:
declare -a fruits=(apples pears plums)
这里创建了一个数组变量fruits, 数组的值使用
括号包围, 元素使用空格分开.
• 使用元素下标访问数组元素, 从0开始. 比如对
上面的数组:
echo ${fruits[0]} # 打印apples
• 数组的遍历, 示例:
for f in ${fruits[@]}; do
echo $f
done
• 示例: demo4.sh
9. 脚本参数
• shell脚本运行时可以指定参数, 可以在shell脚本中使用如
下方式访问这些参数:
$@ 参数数组
$0 shell脚本名称
$1 $2 ... $n 第一个, 第二个...参数
${#1} ${#2}... 第一个, 第二个...参数的长度
${!#} 最后一个参数
$# 参数个数
• 参数遍历, 示例:
for arg in $@; do
echo $arg
done
• 示例: demo5.sh
10. 运算符
- 关系运算符
• 关系运算符
关系运算符指的是对两个变量进行相等以及大小比较, bash中分
为整数关系运算和字符串关系运算. 关系运算返回的结果是true
或者false, 通常是与条件判断语句(if/else)联系在一起的.
1, 整数关系运算符
-eq 等于,如:if [ "$a" -eq "$b" ]
-ne 不等于,如:if [ "$a" -ne "$b" ]
-gt 大于,如:if [ "$a" -gt "$b" ]
-ge 大于等于,如:if [ "$a" -ge "$b" ]
-lt 小于,如:if [ "$a" -lt "$b" ]
-le 小于等于,如:if [ "$a" -le "$b" ]
< 小于(需要双括号),如:(("$a" < "$b"))
<= 小于等于(需要双括号),如:(("$a" <= "$b"))
> 大于(需要双括号),如:(("$a" > "$b"))
>= 大于等于(需要双括号),如:(("$a" >= "$b"))
11. 运算符
- 关系运算符
2, 字符串关系运算符
== 等于,如:if [[ "$a" == "$b" ]],与=等价;
也可以使用单个中括号if [ "$a" == "$b" ]
!= 不等于,如:if [[ "$a" != "$b" ]]
也可以使用单个中括号if [ "$a" != "$b" ]
< 小于,如: if [[ “$a” < “$b” ]]
> 大于,如: if [[ “$a” > “$b” ]]
-z 字符串是否为空, 如: if [ -z “$a” ]
-n 字符串是否非空, 如: if [ -n “$a” ]
注意: 在进行字符串的比较时, 一个好的习惯是使用双引
号将字符串的内容引用起来.
示例: demo6.sh
12. 运算符
- 逻辑运算符
• bash提供了逻辑运算符: &&(与) ||(或) 非(!), 逻辑运算符
可以使用在[[...]]中, 在[...]使用-a代替&&, -o代替||. 示例:
if [[ "$sa" > "abc" && "$sb" < "xyz" ]]...
if [ “$a” = “a” ] && [ “$b” = “b” ]...
if [ "$a" -lt 0 -o "$b" -lt 0 ]...
if [ ! -z “$sa” ]...
• 示例: demo7.sh
• 逻辑运算符的短路行为
对于逻辑与, 如果表达式结果为false停止其他表达式的
执行, 并返回false;
对于逻辑或,如果表达式结果为true停止其他表达式的执
行, 并返回true; 示例:
[ 1 -eq 1 ] || echo 1
[ 1 -eq 2 ] && echo 1
13. 运算符
- 文件测试
• bash提供了很多操作符用于测试文件的属
性, 常用的列举如下:
[ -f FILE ] FILE存在且是一个普通文件
[ -d FILE ] FILE存在且是一个目录
[ -r FILE ] FILE存在且可读
[ -w FILE ] FILE存在且可写
[ -x FILE ] FILE存在且可执行
[ -s FILE ] FILE存在且大小不为0
示例: demo8.sh
14. 条件判断
- if
• bash的条件判断分为if语句 和 case语句:
1, if
if语句可以有如下格式:
if ... then ... fi
if ... then ... else ... fi
if ... then ... elif .... else ... fi
另外在每一个条件分支均可以嵌套if语句, 示例:
count=99
if [ $count -eq 100 ]; then
echo "Count is 100"
else
if [ $count -gt 100 ]; then
echo "Count is greater than 100"
else
echo "Count is less than 100"
fi
fi
15. 条件判断
- case
• case语句用于作多路分支判断, 格式如下:
case variable in
pattern1)
statements
;;
pattern2)
statements
;;
esac
需要注意两点:
1, variable与各个分支指定的字符串进行模式匹配; 如果分
支指定的是*)那么一定可以匹配成功.
2, 如果在某个分支匹配成功, 之后的分支不会被执行;
示例: demo9.sh
16. 循环
- for
• bash支持4中循环语法: for/while/until/select, 这里介
绍常用的for/while循环.
1, for
for循环的语法格式如下:
for variable in word_list
do
statements
done
示例:
for file in `ls`
do
echo $file
done
17. 循环
- while
2, while
while循环使用如下格式:
while ...
do
statements
done
示例:
declare -i a=1
while [ $a -ne 10 ]; do
echo $a
a=a+1
done
示例: demo10.sh
18. 命令替换
• 经常有这样的需求, 将某个命令的结果赋值给一个变量
或者对该结果进行某些操作. bash提供了两种实现方式:
1, 反引号`
variable=`command`
2, $()
variable=$(command)
区别: 在$()中还可以使用反引号进行命令替换, 而反引
号中则不能嵌套反引号.
注意: 如果使用单引号, 则命令替换不会发生; 双引号则可以.
示例:
echo “Today is `date`”
uid=`id -u` && echo $uid
示例: demo11.sh
19. 算数运算
• bash提供了两种方式实现算术运算:
1, 使用declare -i声明整型变量, 示例:
declare -i i=4
i=$i+4
echo $i
2, 使用(()), 示例:
j=4
((j=$j+4))
echo $j
示例: demo12.sh
20. 文件globbing
• bash在解析用户输入的命令时, 如果输入的参数中带有*或者?字
符, 会对该参数进行文件名展开(file globbing); 如果存在匹配该模
式的文件则展开为所有这些匹配的文件名, 如果不存在使用原来
的字符串, 示例:
ls a* # No such file or directory
touch aa ab
ls a* # aa ab
• *&?
* 表示仸意多个字符
? 表示一个字符
注意: 如果需要在字符串中使用*, 则需要使用进行转义, 比如: ls
a*
• bash只会对未使用引号(包括单引号/双引号)的参数进行扩展, 如
果使用了引号则扩展不会发生. 示例: ls “a*”
• 示例: demo13.sh
21. 函数
• 使用function关键字声明一个shell函数, 语法格式:
function func_name() {
statements
}
示例:
function sayHello() {
echo “hello guys”
}
直接使用函数名调用该函数, 比如: sayHello
• 关于函数需要注意以下几点:
1, 调用函数时可以传递参数, 与脚本参数类似在函数类
可以通过$@, $1, $2...引用;
2, 函数内部使用declare命令声明的变量, 只能在函数内
被引用;
• 示例: demo14.sh
Editor's Notes Note: 为什么这里称为”整数关系运算符”? 因为bash本身是不支持浮点运算的,需要使用awk或者其它工具做浮点操作.