Skip to content

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 变量的定义使用规则

  1. 变量名区分大小写,aA为两个不同的变量。
  2. 变量名可以使用大小写字母混编的形式进行编写。
  3. 变量名与值之前的 = 两侧都不能有空格。
  4. 在读取或打印变量时,需使用$加变量名。
  5. 变量可以写在 Bash 脚本中的任何地方,在运行时,Bash 会自动将其替换为变量值。

示例:

name="hogwarts"
echo $name

结果:

hogwarts

数据类型

在 Bash 中声明变量后赋值,它会自动判断数据类型,不必在声明的同时去定义变量的数据类型。

变量的类型

  • 系统定义的变量:通常是以大写字母形式存在,如 BASHSHELL 等。
  • 用户定义的变量:多数以小写字母参与命名,但不具有大小写强制性规定。

示例:

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_1expresion_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_1expresion_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
  • 这个循环遍历了applebananacherry,并依次打印它们。

表达式循环

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

breakcontinue 是俩种用于控制循环流程的命令。

  • 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 函数