Bash编程语法
Bash 编程语法
Bash 简介
Bash 是 Bourne Shell 程序 "sh" 的升级版本,是一个开源 GNU 项目。Bash 是一个命令处理器,通常运行于文本窗口中,可以将用户输入的命令解释并执行相应的操作,这样的文件被称作脚本。
Bash 是绝大多数 Linux、MAC 及 OS 默认的 shell 程序。
Bash 特点
- Bash 与 sh 兼容,并具有 Korn Shell 和 C Shell 的最佳功能特性。
- Bash 中的每个文件都有其特定用途,这些文件的集合用于创建环境。
- Bash 可以通过键位绑定设置自定义的编辑键序列。
- Bash 包含了一维数组,它们可以帮助您轻松的引用和操作数据列表。
- Bash 中的目录堆栈指定了列表中最近访问的目录历史记录。操作示例:pushed 用于将目录添加至堆栈中;popd 用于将目录从堆栈中删除;dirs 用于显示堆栈中的内容。
- Bash 包含用于环境安全的受限模式。
Bash 变量
变量的定义
在 Bash 中,变量的定义非常简单,只需要将变量名和值用=
连接即可。
语法:
Variable_name=value
Bash 变量的定义使用规则
- 变量名区分大小写,
a
和A
为两个不同的变量。 - 变量名可以使用大小写字母混编的形式进行编写。
- 变量名与值之前的
=
两侧都不能有空格。 - 在读取或打印变量时,需使用
$
加变量名。 - 变量可以写在 Bash 脚本中的任何地方,在运行时,Bash 会自动将其替换为变量值。
示例:
name="hogwarts"
echo $name
结果:
hogwarts
数据类型
在 Bash 中声明变量后赋值,它会自动判断数据类型,不必在声明的同时去定义变量的数据类型。
变量的类型
- 系统定义的变量:通常是以大写字母形式存在,如
BASH
、SHELL
等。 - 用户定义的变量:多数以小写字母参与命名,但不具有大小写强制性规定。
示例:
name="abc"
echo $name
echo $BASH
结果:
abc
/usr/bin/bash
只读变量
使用 readonly
命令可以将变量设置为只读,无法修改其值。
示例:
a="123"
readonly a
a="456" #此操作将失败
echo $a
结果:
line 3: a: readonly variable
123
- 变量
a
被设置为只读,尝试修改其值会导致错误。
删除变量
使用unset
命令可以删除变量。
示例:
variable_name="some_value"
unset variable_name
echo $variable_name # 不会输出任何内容
- 变量
variable_name
被删除后,使用$variable_name
读取其值将不会输出任何内容。
字符串的拼接
示例:
str1="Hello"
str2="World"
str3="${str1} ${str2}"
echo $str3
结果:
Hello World
- 使用
${str1}
和${str2}
进行字符串拼接,结果赋值给str3
。
Bash 引号
在 Bash 中,可以使用单引号
和双引号
来处理字符串,使用不同的引号方式会对字符串解析产生不同的效果。
单引号和双引号的区别
- 单引号
''
:将字符串内的所有内容原样输出,不进行变量替换或命令替换。 - 双引号
""
:允许对字符串内的变量和命令进行替换。
示例:
name="hogwarts"
echo "Hello, $name" # 使用双引号可以解析变量
echo 'Hello, $name' # 使用单引号不会解析变量
结果:
Hello, John
Hello, $name
- 使用双引号时,变量
$name
被解析为值hogwarts
,而使用单引号时,变量名$name
被原样输出。
Bash 数组
数组可以定义为相似类型元素的集合,在 Bash 中数组不必是相似类型元素的集合。
索引数据的声明和赋值
示例:
通过 declare -a
声明一个索引数组,并通过键赋值。
declare -A Array_Name
Array_Name["name1"]="value_1"
Array_Name["name2"]="value_2"
# 或
Array_Name=(
["name1"]="value_1"
["name2"]="value_2"
)
关联数组的声明和赋值
使用 declare -A
声明一个关联数组,并通过键赋值。
示例:
declare -A Array_Name
Array_Name["name1"]="value_1"
Array_Name["name2"]="value_2"
# 或
Array_Name=(
["name1"]="value_1"
["name2"]="value_2"
)
数组的访问
使用数组的索引或键来访问数组中的元素。
示例:
declare -a arr1=("hello" "world")
declare -A arr2=(["key1"]="hello" ["key2"]="world")
echo ${arr1[1]}
echo ${arr2["key1"]}
结果:
world
hello
取出所有元素
${arr[@]}
和 ${arr[*]}
都可以取出数组中的所有元素。
示例:
declare -a arr1=("hello" "world")
echo ${arr1[@]}
echo ${arr1[*]}
结果:
hello world
hello world
向数组中添加元素
使用 +=
运算符或指定索引
来向数组中添加元素。
示例:
declare -a arr=("hello" "world")
arr+=("hogwarts")
arr[5]="harry"
echo ${arr[*]}
结果:
hello world hogwarts harry
输出索引
${!arr[@]}
返回数组中所有元素的索引。
示例:
declare -a arr=("hello" "world")
arr+=("hogwarts")
arr[5]="harry"
echo "arr indexes are ${!arr[@]}"
结果:
arr indexes are 0 1 2 5
if 控制语句
控制语句用于根据条件执行不同的命令,常见的控制语句包括 if
语句。
单条件
语法:
如果 expression
为真,则执行 statements
。
if [ expression ]; then
statements
fi
示例:
age=18
if [ $age == 18 ]; then
echo "You are an adult."
fi
结果:
You are an adult.
- 如果
age
等于 18,则输出 "You are an adult."
多条件与
语法:
如果 expression_1
和 expresion_2
都为真,则执行 statements
。
if [ expression_1 ] && [ expression_2 ]; then
statements
fi
示例:
age=18
country="USA"
if [ $age -ge 18 ] && [ "$country" == "USA" ]; then
echo "You are an adult in the USA."
fi
结果:
You are an adult in the USA.
- 如果
age
大于或等于 18 且country
等于 "USA",则输出 "You are an adult in the USA."。
多条件或
语法:
如果 expreion_1
或 expresion_2
为真,则执行 statements
。
示例:
age=16
country="USA"
if [ $age == 18 ] || [ "$country" == "USA" ]; then
echo "You are either an adult or in the USA."
fi
结果:
You are either an adult or in the USA.
- 如果
age
等于 18 或 country 等于 "USA",则输出 "You are either an adult or in the USA."。
多分支
语法:
如果 expression_1
为真,则执行第一个 statements
;否则,如果 expression_2
为真,则执行第二个 statements
;如果都不为真,则执行 else
部分的 statements
。
if [ expression_1 ]; then
statements
elif [ expression_2 ]; then
statements
else
statements
fi
示例:
age=17
if [ $age -ge 18 ]; then
echo "You are an adult."
elif [ $age -ge 13 ]; then
echo "You are a teenager."
else
echo "You are a child."
fi
结果:
You are a teenager.
- 根据
age
的值输出相应的消息。
循环语句
在 Bash 编程中,循环语句用于重复执行一组命令,主要有for
循环和while
循环。
for 循环
for
循环用于遍历列表中的每一个元素,并对每一个元素执行相同的一组命令。
基本语法:
for variable in list; do
commands
done
- 在这个语法中,
variable
是一个临时变量,它依次取list
中的每一个值,然后执行commands
。
示例:
for fruit in apple banana cherry; do
echo $fruit
done
结果:
apple
banana
cherry
- 这个循环遍历了
apple
、banana
和cherry
,并依次打印它们。
表达式循环
for
循环也可以通过表达式来控制循环次数。
基础语法:
for (( expression1; expression2; expression3 )); do
commands
done
- 在这个语句中,
expression1
用于初始化循环变量,expression2
用于设置循环继续的条件,expression3
用于更新循环变量。
示例:
for ((i = 1; i <= 5; i++)); do
echo $i
done
结果:
1
2
3
4
5
- 这个循环从 1 开始,每次循环后变量
i
增加 1,直到i
大于 5。
循环范围
通过大括号 {}
可以指定一个范围来循环。
示例:
for num in {5..0..1}; do
echo $num
done
结果:
5
4
3
2
1
0
- 这个循环从 5 开始,每次减少 1,直到 0.
循环数组
for
循环也可以用来遍历数据中的每一个元素。
示例:
arr=("Welcome" "to" "hogwarts")
for i in "${arr[@]}"; do
echo $i
done
结果:
Welcome
to
hogwarts
- 这个循环遍历数据
arr
中的每一个元素,并依次打印它们。
@ 与 * 的区别
${arr[@]}
和 ${arr[*]}
都可以用来引用数据的所有元素,但在某些情况下会有区别
示例:
arr=("Welcome" "to" "hogwarts")
# 使用 @
for i in ${arr[@]}; do
echo $i
done
# 使用 *
for i in ${arr[*]}; do
echo $i
done
# 使用双引号和 *
for i in "${arr[*]}"; do
echo $i
done
结果:
# 使用 @
Welcome
to
hogwarts
# 使用 *
Welcome
to
hogwarts
# 使用双引号和 *
Welcome to hogwarts
- 使用
${arr[@]}
或${arr[*]}
会将数组展开为单个字符串。 - 使用双引号和
${arr[*]}
会将数组的所有元素当作一个字符串处理。
while 循环
while
循环用于在满足某个条件时重复执行一组命令。
基本语法:
while [ expression ]; do
commands
done
- 在这个语法中,当
expression
为 True 时,执行commands
,直到expression
为 False。
示例:
count=1
while [ $count -le 5 ]; do
echo $count
((count++))
done
输出:
1
2
3
4
5
- 这个循环从
count
等于 1 开始,每次循环后count
增加 1,直到count
大于 5。
break 与 continue
break
和 continue
是俩种用于控制循环流程的命令。
break
语句可以终止循环的执行。continue
语句可以路过循环中的某些命令,继续下一次循环。
break 示例
for i in {1..5}; do
if [ $i == 3 ]; then
break
fi
echo $i
done
结果:
1
2
- 当
i
等于 3 时,break
语句终止了循环。
continue 示例
for i in {1..5}; do
if [ $i == 3 ]; then
continue
fi
echo $i
done
结果:
1
2
4
5
- 当
i
等于 3 时,continue
语句路过了当前的循环迭代,继续下一次循环。
Bash 函数
定义函数
基本语法:
function_name(){
commands
}
变量的作用域
- 默认情况下所有变量都定义为
全局变量
,即使在函数内部声明也是如此。 - 使用
local
关键字在函数内部声明局部变量,该变量只能够在该函数内部使用。
返回值
- Bash 函数中,其返回值是执行的最后一个语句的状态,1-255(十进制)范围内表示失败,除此之外表示成功。
- 想要从函数中返回任意实际的值,最简单的选择是将函数的执行结果分配给一个全局变量。
- 更好的选择是将值发送到 stdout 再打印输出。
参数传递
$0
为函数本身$1
、$2
···$n
参数传递的顺序位$#
保存传递给函数的函数的位置参数或数量$$
当前进程 ID 号$*
或$@
保存传递给参数的所有位置参数或参数$?
显示最后一个命令的退出状态,0 表示正常,其他表示错误退出
案例
- 案例 1,判断一个数字是否为正数
#!/bin/bash
# 判断输入的数字是否为正数
check_positive() {
if [ $1 -gt 0 ]; then
echo "$1 是正数"
else
echo "$1 不是正数"
fi
}
# 调用函数并传递参数
check_positive 5
check_positive -3
总结
- Bash 简介
- Bash 特点
- Bash 变量
- Bash 引号
- Bash 数组
- if 控制语句
- 循环语句
- Bash 函数