#!
告诉系统其后面的路径指定的程序就是此脚本文件的shell程序。
注释
- 单行注释:
#
- 多行注释:
#!/bin/bash
:<<EOF
注释内容 ...
EOF
变量
定义普通变量
变量名=变量值
- 变量名和等号之间不能有空格
- 命名只能使用英文字母、数字、下划线,首字符不能以数字开头
- 变量名不能与bash关键字同名
for
循环语法定义变量
#!/bin/bash
for file in `ls /etc`
do
echo $file
done
# 打印/etc下的所有文件
定义只读变量
- 使用
readonly
关键字可以将普通变量定义为只读变量
#!/bin/bash
name="ahaoozhang"
readonly name
# name被声明为只读变量,如果代码中出现修改name的行为时,程序将会报错
使用变量
- 使用一个定义过的变量,需要在变量名前加上美元符
$
#!/bin/bash
name="ahaoozhang"
echo $name
echo ${name}
# {}大括号可以有效的让代码解释器识别变量名的边界
删除变量
- 使用关键字
unset
可以删除普通变量,unset
不能删除只读变量,被删除的变量不能被再次使用
变量类型
- 局部变量:仅在当前shell中有效的变量
- 环境变量:所有的程序都能访问的变量
- shell变量
字符串
定义字符串可以用单引号、双引号、也可以不用引号
单引号字符串的限制:
- 单引号字符串中的任何字符都会原样输出,在单引号字符串中使用变量是无效的
- 单引号字符串中不能使用转义字符
拼接字符串
- 使用双引号拼接
#!/bin/bash
name="ahaoozhang"
str="my name is $name"
# 在双引号字符串中使用变量名拼接字符串
- 使用单引号拼接
#!/bin/bash
name="ahaoozhang"
str='my name is '$name''
# 在单引号中使用变量需要另外使用单引号括起来
获取字符串长度
- 使用
#
字符
#!/bin/bash
name="ahaoozhang"
echo ${#name} # 输出name字符串的长度
字符串切片
#!/bin/bash
name="ahaoozhang"
echo ${name:1:4} #从name字符串的第二个字符向后截取4个字符
查找字符串中字符第一次出现的位置
#!/bin/bash
name="ahaoozhang"
echo `expr index "$name" oz` # 查找name字符串中o/z字符第一次出现的位置,哪一个先出现就返回哪一个的位置
数组
- shell数组中元素的类型不一定一致,数字、字符串等不同的元素可以位于同一个数组内
数组定义
- 统一初始化
#!/bin/bash
arr1=("ahaoozhang" 18 "man")
arr2=(
"ahaoozhang"
18
"nan"
)
- 单独元素赋值:可以不使用连续的下标赋值
#!/bin/bash
arr3[0]="ahaoozhang"
arr3[2]=18
arr3[3]="man"
读取数组
${数组名[数组下标]}
获取数组的长度
- 使用
#
+@
/*
#!/bin/bash
arr4=(1 2 3 4 5)
length=${#arr4[@]}
length=${#arr4[*]}
遍历数组
- 标准for循环
#!/bin/bash
arr5=("ahaoozhang" 18 "man")
# 标准for循环
for((i=0;i<${#arr5[@]};i++)); do
# TODO
done
- for语法糖
#!/bin/bash
arr5=("ahaoozhang" 18 "man")
# for ... in ... 无下标
for item in ${arr5[@]} do
# TODO
done
# for ... in ... 有下标
for item in ${!arr5[@]} do
# TODO
done
- while循环
#!/bin/bash
arr5=("ahaoozhang" 18 "man")
i=0
while [ $i -lt ${#arr5[@]} ]
do
# TODO
let i++
done
流程控制
if语句
#!/bin/bash
# if 语法格式
if 条件判断
then
# TODO
fi
# if else语法格式
if 条件判断
then
# TODO
else
# TODO
fi
# if else-if else语法格式
if 条件判断1
then
# TODO
elif 条件判断2
then
# TODO
else
# TODO
fi
case语句
case 变量 in
匹配值1)
# TODO
;;
匹配值2)
# TODO
;;
esac
for循环
#!/bin/bash
# 标准for循环
for((变量;条件判断;变量动作)); do
# TODO
done
# 语法糖for
for item in item1 item2 ... itemN
do
# TODO
done
while循环
#!/bin/bash
while 条件判断
do
# TODO
done
# 死循环 该写法不支持单行shell
while :
do
# TODO
done
while true
do
# TODO
done
# 读取键盘输入
while read R
do
# R代表当前键盘输入的值
done
until循环
until循环指代执行一系列命令直到条件表达式为true时停止。
#!/bin/bash
until 条件表达式
do
# TODO
done
break/continue
break
跳出所有的循环continue
仅跳出当前循环
运算符
条件表达式要放在[]方括号之间,并且两边必须要有空格
算术运算符
#!/bin/bash
a=1
b=2
if [ $a == $b ]
then
echo "a==b"
fi
# 方括号与变量之间的空格是必须存在的
关系运算符
- 关系运算符只支持数字,不支持字符串。
运算符 | 描述 |
---|---|
-eq | 检测两个数字是否相等,与==类似 |
-ne | 检测两个数字是否不相等,与!=类似 |
-gt | 检测左边的数是否大于右边,与>类似 |
-lt | 检测左边的数字是否小于与右边,与<类似 |
-ge | 检测左边的数字是否大于等于右边,与>=类似 |
-le | 检测左边的数字是否小于等于右边,与<=类似 |
因为在bash中< << > >>
被用作重定向符号,所以为了不引起歧义,所以使用上面的符号进行条件判断。
布尔运算符
运算符 | 描述 |
---|---|
! | 非运算 |
-o | 或运算 |
-a | 与运算 |
在bash中|
被用作管道符号,&
被用作后台运行符号。
逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑且 |
|| | 逻辑或 |
字符串运算符
运算符 | 描述 |
---|---|
= | 判断两个字符串是否相等 |
!= | 判断两个字符串是否不相等 |
-z | 检测字符串长度是否为0 |
-n | 检测字符串长度是否不为0 |
$ | 检测字符串是否为空 |
文件测试运算符
运算符 | 描述 |
---|---|
-b FILEPATH | 判断文件是否为块设备 |
-c FILEPATH | 判断文件是否为字符设备文件 |
-d FILEPATH | 判断文件是否为目录文件 |
-f FILEPATH | 判断文件是否为普通文件 |
-g FILEPATH | 判断文件是否设置了SGID位 |
-k FILEPATH | 判断文件是否设置了粘滞位 |
-p FILEPATH | 判断文件是否是命名管道文件 |
-u FILEPATH | 判断文件是否设置了SUID位 |
-r FILEPATH | 判断文件是否可读 |
-w FILEPATH | 判断文件是否可写 |
-x FILEPATH | 判断文件是否可执行 |
-s FILEPATH | 判断文件是否为空 |
-e FILEPATH | 检测文件是否存在 |
函数
- 返回值:如果函数没有添加返回值,会以最后一条命令的运行结果作为返回值。
#!/bin/bash
demoFunc() {
echo "hello world!"
}
函数传参
- 使用
$n
获取参数:当参数超过10个时,需要使用{}为解释器指明目标参数
#!/bin/bash
demoFunc() {
echo "第一个参数$1"
echo "第一个参数$2"
}
# 使用函数名可以执行函数
demoFunc 1 2
# 第一个参数1
# 第一个参数2
参数 | 描述 |
---|---|
$# | 参数个数 |
$* | 以一个单字符串传递所有参数 |
$$ | 脚本运行的当前进程PID号 |
$! | 后台运行的最后一个进程的PID号 |
$@ | 以一个单字符串传递所有参数,使用时加引号,并在引号中返回每个参数 |
$- | 显示shell使用的当前选项,类似set |
$? | 显示最后命令的错误码 |
输入输出重定向
重定向符号 | 描述 |
---|---|
process > file | 将进程的标准输出重定向到文件file |
process < file | 将进程的标准输入重定向到文件file |
process >> file | 将进程的标准输出以追加方式重定向到文件file |
n > file | 将文件描述符为n的文件重定向到文件file |
n >> file | 将文件描述符为n的文件以追加方式重定向到文件file |
n >& m | 将输出文件m和n合并 |
n <& m | 将输入文件m和n合并 |
<< tag | 将开始标记tag和结束标记tag之间的内容作为输出 |
/dev/null
- 任何写入
/dev/null
的内容都将会被抛弃,相当与系统垃圾桶