From b8490936bc057d167a78d867468ff86f4887166e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9F=B6=E4=B8=83=E6=AD=A3?= <13103684+bai-jianan@user.noreply.gitee.com> Date: Sat, 25 Apr 2026 10:37:07 +0000 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 韶七正 <13103684+bai-jianan@user.noreply.gitee.com> --- Snipaste_2026-04-25_18-30-51.jpg | Bin 0 -> 109304 bytes bash-arithmetic-operations.sh | 108 +++++++++++++++++++++++++ bash-array-operations.sh | 107 ++++++++++++++++++++++++ bash-builtin-commands.sh | 115 ++++++++++++++++++++++++++ bash-c-command-execution.sh | 92 +++++++++++++++++++++ bash-conditional-statements.sh | 128 +++++++++++++++++++++++++++++ bash-function-features.sh | 134 +++++++++++++++++++++++++++++++ bash-io-redirection.sh | 109 +++++++++++++++++++++++++ bash-loop-control.sh | 127 +++++++++++++++++++++++++++++ bash-process-substitution.sh | 104 ++++++++++++++++++++++++ bash-script-options.sh | 133 ++++++++++++++++++++++++++++++ bash-string-operations.sh | 106 ++++++++++++++++++++++++ bash-variable-expansion.sh | 113 ++++++++++++++++++++++++++ 13 files changed, 1376 insertions(+) create mode 100644 Snipaste_2026-04-25_18-30-51.jpg create mode 100644 bash-arithmetic-operations.sh create mode 100644 bash-array-operations.sh create mode 100644 bash-builtin-commands.sh create mode 100644 bash-c-command-execution.sh create mode 100644 bash-conditional-statements.sh create mode 100644 bash-function-features.sh create mode 100644 bash-io-redirection.sh create mode 100644 bash-loop-control.sh create mode 100644 bash-process-substitution.sh create mode 100644 bash-script-options.sh create mode 100644 bash-string-operations.sh create mode 100644 bash-variable-expansion.sh diff --git a/Snipaste_2026-04-25_18-30-51.jpg b/Snipaste_2026-04-25_18-30-51.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cd08b66f701d564efc83ad06978864de3fbf0815 GIT binary patch literal 109304 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 G{C@#=Hum=b literal 0 HcmV?d00001 diff --git a/bash-arithmetic-operations.sh b/bash-arithmetic-operations.sh new file mode 100644 index 0000000..4143190 --- /dev/null +++ b/bash-arithmetic-operations.sh @@ -0,0 +1,108 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-003-bash-arithmetic-operations +# @用例名称: bash-arithmetic-operations +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 算术运算功能,包括 $(()) 算术展开、let 命令、(()) 复合命令、位运算以及比较运算等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 使用 $(()) 进行加法运算 + # @预期结果: 加法结果正确 + result=$((10 + 5)) + assert_true [ "$result" -eq 15 ] + + # @测试步骤: 使用 $(()) 进行减法运算 + # @预期结果: 减法结果正确 + result=$((20 - 8)) + assert_true [ "$result" -eq 12 ] + + # @测试步骤: 使用 $(()) 进行乘法运算 + # @预期结果: 乘法结果正确 + result=$((6 * 7)) + assert_true [ "$result" -eq 42 ] + + # @测试步骤: 使用 $(()) 进行除法运算 + # @预期结果: 整除结果正确 + result=$((15 / 4)) + assert_true [ "$result" -eq 3 ] + + # @测试步骤: 使用 $(()) 进行取模运算 + # @预期结果: 取模结果正确 + result=$((17 % 5)) + assert_true [ "$result" -eq 2 ] + + # @测试步骤: 使用 $(()) 进行幂运算 + # @预期结果: 幂运算结果正确 + result=$((2 ** 8)) + assert_true [ "$result" -eq 256 ] + + # @测试步骤: 使用 let 命令进行算术运算 + # @预期结果: let 命令运算结果正确 + let "val = 3 * 4 + 2" + assert_true [ "$val" -eq 14 ] + + # @测试步骤: 使用 (()) 复合命令作为条件判断 + # @预期结果: 条件为真时返回 0 + (( 5 > 3 )) + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 (()) 复合命令进行自增操作 + # @预期结果: 自增结果正确 + counter=10 + (( counter++ )) + assert_true [ "$counter" -eq 11 ] + + # @测试步骤: 使用位与运算 + # @预期结果: 位运算结果正确 + result=$(( 12 & 10 )) + assert_true [ "$result" -eq 8 ] + + # @测试步骤: 使用位或运算 + # @预期结果: 位或运算结果正确 + result=$(( 12 | 3 )) + assert_true [ "$result" -eq 15 ] + + # @测试步骤: 使用左移运算 + # @预期结果: 左移结果正确 + result=$(( 1 << 4 )) + assert_true [ "$result" -eq 16 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-array-operations.sh b/bash-array-operations.sh new file mode 100644 index 0000000..a5155b8 --- /dev/null +++ b/bash-array-operations.sh @@ -0,0 +1,107 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-004-bash-array-operations +# @用例名称: bash-array-operations +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 数组功能,包括数组声明、元素赋值访问、数组长度、数组切片、遍历、删除元素以及关联数组操作 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 声明并初始化索引数组 + # @预期结果: 数组元素可以正确访问 + arr=(apple banana cherry) + assert_true [ "${arr[0]}" = "apple" ] + assert_true [ "${arr[1]}" = "banana" ] + assert_true [ "${arr[2]}" = "cherry" ] + + # @测试步骤: 获取数组长度 + # @预期结果: 返回正确的元素个数 + arr=(one two three four five) + len="${#arr[@]}" + assert_true [ "$len" -eq 5 ] + + # @测试步骤: 修改数组元素 + # @预期结果: 元素被正确修改 + arr[1]="modified" + assert_true [ "${arr[1]}" = "modified" ] + + # @测试步骤: 获取所有数组元素 + # @预期结果: 所有元素正确展开 + arr=(x y z) + all="${arr[@]}" + echo "$all" | grep -q "x" + assert_true [ $? -eq 0 ] + echo "$all" | grep -q "z" + assert_true [ $? -eq 0 ] + + # @测试步骤: 数组切片操作 + # @预期结果: 切片返回正确的子数组 + arr=(a b c d e) + slice=("${arr[@]:1:3}") + assert_true [ "${slice[0]}" = "b" ] + assert_true [ "${slice[2]}" = "d" ] + + # @测试步骤: 追加元素到数组 + # @预期结果: 元素成功追加,长度增加 + arr=(1 2 3) + arr+=(4 5) + assert_true [ "${#arr[@]}" -eq 5 ] + assert_true [ "${arr[4]}" = "5" ] + + # @测试步骤: 使用 unset 删除数组元素 + # @预期结果: 元素被删除 + arr=(p q r) + unset 'arr[1]' + assert_true [ -z "${arr[1]}" ] + + # @测试步骤: 关联数组(declare -A)赋值与访问 + # @预期结果: 键值对可以正确存取 + declare -A assoc + assoc["key1"]="value1" + assoc["key2"]="value2" + assert_true [ "${assoc[key1]}" = "value1" ] + assert_true [ "${assoc[key2]}" = "value2" ] + + # @测试步骤: 获取关联数组所有键 + # @预期结果: 所有键可以正确枚举 + keys=("${!assoc[@]}") + assert_true [ "${#keys[@]}" -eq 2 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-builtin-commands.sh b/bash-builtin-commands.sh new file mode 100644 index 0000000..52b6cf3 --- /dev/null +++ b/bash-builtin-commands.sh @@ -0,0 +1,115 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-011-bash-builtin-commands +# @用例名称: bash-builtin-commands +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 常用内置命令功能,包括 declare、export、readonly、source、eval、trap、getopts、shift 以及 type 等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_source_file="$g_tmpdir/sourced.sh" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包,准备 source 用的脚本文件 + assert_true yum install -y bash + cat > "$g_source_file" <<'EOF' +sourced_var="from_source" +sourced_func() { echo "sourced_func_output"; } +EOF + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 使用 declare -i 声明整型变量 + # @预期结果: 整型变量不允许非数值赋值,数学赋值自动计算 + declare -i int_var=10 + int_var+=5 + assert_true [ "$int_var" -eq 15 ] + + # @测试步骤: 使用 declare -r 声明只读变量 + # @预期结果: 只读变量不能被修改(修改返回非 0) + declare -r readonly_var="immutable" + assert_true [ "$readonly_var" = "immutable" ] + ( readonly_var="changed" ) > /dev/null 2>&1 + assert_true [ $? -ne 0 ] + + # @测试步骤: 使用 export 导出变量到子进程 + # @预期结果: 子进程可以访问被 export 的变量 + export EXPORTED_VAR="exported_value" + result=$(bash -c 'echo $EXPORTED_VAR') + assert_true [ "$result" = "exported_value" ] + + # @测试步骤: 使用 source 加载外部脚本文件 + # @预期结果: 外部脚本中的变量和函数可以被当前 shell 使用 + source "$g_source_file" + assert_true [ "$sourced_var" = "from_source" ] + output=$(sourced_func) + assert_true [ "$output" = "sourced_func_output" ] + + # @测试步骤: 使用 eval 动态执行代码 + # @预期结果: eval 正确执行动态生成的命令 + cmd="result_eval=eval_worked" + eval "$cmd" + assert_true [ "$result_eval" = "eval_worked" ] + + # @测试步骤: 使用 shift 移动位置参数 + # @预期结果: shift 正确移除第一个参数,其余参数前移 + test_shift() { + shift + echo "$1" + } + output=$(test_shift "first" "second" "third") + assert_true [ "$output" = "second" ] + + # @测试步骤: 使用 type 检查命令类型 + # @预期结果: 内置命令被识别为 builtin,外部命令被识别为文件 + type -t echo | grep -q "builtin" + assert_true [ $? -eq 0 ] + type -t ls | grep -q "file" + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 trap 捕获 EXIT 信号 + # @预期结果: 退出时 trap 命令被执行,标记文件被创建 + local trap_flag="$g_tmpdir/trap_flag.txt" + ( + trap "touch $trap_flag" EXIT + exit 0 + ) + assert_true test -f "$trap_flag" + + # @测试步骤: 使用 readonly 限制变量修改 + # @预期结果: readonly 变量的值不能被改变 + readonly RO_VAR="fixed" + assert_true [ "$RO_VAR" = "fixed" ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + unset EXPORTED_VAR + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-c-command-execution.sh b/bash-c-command-execution.sh new file mode 100644 index 0000000..1a15428 --- /dev/null +++ b/bash-c-command-execution.sh @@ -0,0 +1,92 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-001-bash-c-command-execution +# @用例名称: bash-c-command-execution +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash -c 选项能够执行字符串命令,包括简单命令、变量展开、命令替换和管道等场景 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 使用 bash -c 执行简单 echo 命令 + # @预期结果: 命令执行成功,输出正确 + output=$(bash -c 'echo hello_bash') + assert_true [ $? -eq 0 ] + echo "$output" | grep -q "hello_bash" + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 bash -c 执行包含变量的命令 + # @预期结果: 变量能正确传递和展开 + output=$(bash -c 'var=testval; echo $var') + echo "$output" | grep -q "testval" + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 bash -c 执行命令替换 + # @预期结果: 命令替换结果正确 + output=$(bash -c 'echo $(echo nested)') + echo "$output" | grep -q "nested" + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 bash -c 执行管道命令 + # @预期结果: 管道命令执行成功,输出正确 + output=$(bash -c 'echo "line1\nline2\nline3" | wc -l') + assert_true [ $? -eq 0 ] + [ "$output" -ge 1 ] + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 bash -c 执行算术运算 + # @预期结果: 算术计算结果正确 + output=$(bash -c 'echo $((3 + 4))') + echo "$output" | grep -q "7" + assert_true [ $? -eq 0 ] + + # @测试步骤: bash -c 执行失败命令时返回非 0 退出码 + # @预期结果: 不存在的命令返回非 0 退出码 + bash -c 'command_not_exist_xyz' > /dev/null 2>&1 + assert_true [ $? -ne 0 ] + + # @测试步骤: 使用 bash -c 并通过 $0 $1 传递参数 + # @预期结果: 位置参数正确传递 + output=$(bash -c 'echo $1 $2' bash_test arg1 arg2) + echo "$output" | grep -q "arg1" + assert_true [ $? -eq 0 ] + echo "$output" | grep -q "arg2" + assert_true [ $? -eq 0 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-conditional-statements.sh b/bash-conditional-statements.sh new file mode 100644 index 0000000..efe7935 --- /dev/null +++ b/bash-conditional-statements.sh @@ -0,0 +1,128 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-005-bash-conditional-statements +# @用例名称: bash-conditional-statements +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 条件语句功能,包括 if/elif/else、case 语句、[[ ]] 扩展测试、文件测试运算符、字符串比较运算符等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_testfile="$g_tmpdir/testfile.txt" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包并准备测试文件 + assert_true yum install -y bash + echo "test content" > "$g_testfile" + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 测试 if/else 基本条件判断 + # @预期结果: 条件为真时执行 if 分支 + val=10 + if [ "$val" -gt 5 ]; then + result="greater" + else + result="not_greater" + fi + assert_true [ "$result" = "greater" ] + + # @测试步骤: 测试 if/elif/else 多分支 + # @预期结果: 正确进入匹配的分支 + score=75 + if [ "$score" -ge 90 ]; then + grade="A" + elif [ "$score" -ge 70 ]; then + grade="B" + else + grade="C" + fi + assert_true [ "$grade" = "B" ] + + # @测试步骤: 使用 [[ ]] 测试字符串匹配(== 通配符) + # @预期结果: 通配符匹配正确 + filename="testfile.txt" + [[ "$filename" == *.txt ]] + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 [[ ]] 测试正则匹配(=~ 运算符) + # @预期结果: 正则表达式匹配正确 + str="hello123" + [[ "$str" =~ ^[a-z]+[0-9]+$ ]] + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 case 语句匹配字符串 + # @预期结果: case 语句正确匹配并执行相应分支 + day="Monday" + case "$day" in + Monday|Tuesday|Wednesday|Thursday|Friday) + dtype="weekday" + ;; + Saturday|Sunday) + dtype="weekend" + ;; + *) + dtype="unknown" + ;; + esac + assert_true [ "$dtype" = "weekday" ] + + # @测试步骤: 测试文件存在性 -f + # @预期结果: 已创建的测试文件被识别为普通文件 + assert_true test -f "$g_testfile" + + # @测试步骤: 测试目录存在性 -d + # @预期结果: 已创建的临时目录被识别为目录 + assert_true test -d "$g_tmpdir" + + # @测试步骤: 测试文件非空 -s + # @预期结果: 有内容的文件 -s 为真 + assert_true test -s "$g_testfile" + + # @测试步骤: 测试字符串非空 -n + # @预期结果: 非空字符串返回真 + nonempty="hello" + assert_true test -n "$nonempty" + + # @测试步骤: 测试字符串为空 -z + # @预期结果: 空字符串返回真 + empty="" + assert_true test -z "$empty" + + # @测试步骤: 测试 && 和 || 逻辑运算符 + # @预期结果: 逻辑与/或运算结果正确 + true && result_and="ok" + assert_true [ "$result_and" = "ok" ] + false || result_or="ok" + assert_true [ "$result_or" = "ok" ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-function-features.sh b/bash-function-features.sh new file mode 100644 index 0000000..f794cae --- /dev/null +++ b/bash-function-features.sh @@ -0,0 +1,134 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-007-bash-function-features +# @用例名称: bash-function-features +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 函数功能,包括函数定义、调用、参数传递、返回值、局部变量、递归以及函数作为命令替换等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +# 辅助函数:简单加法 +add_numbers() { + local a="$1" + local b="$2" + echo $((a + b)) +} + +# 辅助函数:判断数字奇偶,返回 0 表示偶数,1 表示奇数 +is_even() { + local n="$1" + [ $((n % 2)) -eq 0 ] +} + +# 辅助函数:递归计算阶乘 +factorial() { + local n="$1" + if [ "$n" -le 1 ]; then + echo 1 + else + local sub + sub=$(factorial $((n - 1))) + echo $((n * sub)) + fi +} + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 调用简单函数并通过命令替换捕获输出 + # @预期结果: 函数返回正确的计算结果 + result=$(add_numbers 7 8) + assert_true [ "$result" -eq 15 ] + + # @测试步骤: 函数返回值(return 语句) + # @预期结果: return 返回正确的退出码 + is_even 4 + assert_true [ $? -eq 0 ] + is_even 5 + assert_true [ $? -ne 0 ] + + # @测试步骤: 函数内局部变量不影响外部变量 + # @预期结果: 局部变量作用域仅限函数内部 + outer_var="original" + test_local() { + local outer_var="changed" + echo "$outer_var" + } + inner_output=$(test_local) + assert_true [ "$inner_output" = "changed" ] + assert_true [ "$outer_var" = "original" ] + + # @测试步骤: 函数接收位置参数 $1 $2 $@ + # @预期结果: 位置参数正确传递 + check_params() { + assert_true [ "$1" = "first" ] + assert_true [ "$2" = "second" ] + assert_true [ "$#" -eq 2 ] + } + check_params "first" "second" + + # @测试步骤: 递归函数计算阶乘 + # @预期结果: 递归计算 5! = 120 + result=$(factorial 5) + assert_true [ "$result" -eq 120 ] + + # @测试步骤: 函数可以修改全局变量 + # @预期结果: 全局变量被函数正确修改 + g_counter=0 + increment_counter() { + g_counter=$((g_counter + 1)) + } + increment_counter + increment_counter + increment_counter + assert_true [ "$g_counter" -eq 3 ] + + # @测试步骤: 通过 typeset -f 检查函数是否已定义 + # @预期结果: 已定义的函数可以被 typeset -f 识别 + typeset -f add_numbers > /dev/null 2>&1 + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 unset -f 删除函数定义 + # @预期结果: 删除后函数不再存在 + temp_func() { echo "temp"; } + typeset -f temp_func > /dev/null 2>&1 + assert_true [ $? -eq 0 ] + unset -f temp_func + typeset -f temp_func > /dev/null 2>&1 + assert_true [ $? -ne 0 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-io-redirection.sh b/bash-io-redirection.sh new file mode 100644 index 0000000..01ffc39 --- /dev/null +++ b/bash-io-redirection.sh @@ -0,0 +1,109 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-008-bash-io-redirection +# @用例名称: bash-io-redirection +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 输入输出重定向功能,包括标准输出重定向、追加重定向、标准错误重定向、输入重定向、Here Document、Here String 以及管道等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_outfile="$g_tmpdir/output.txt" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 标准输出重定向到文件(>) + # @预期结果: 文件被创建并包含正确内容 + echo "redirect_test" > "$g_outfile" + assert_true test -f "$g_outfile" + grep -q "redirect_test" "$g_outfile" + assert_true [ $? -eq 0 ] + + # @测试步骤: 追加重定向(>>) + # @预期结果: 内容追加到文件末尾,原内容不被覆盖 + echo "line1" > "$g_outfile" + echo "line2" >> "$g_outfile" + line_count=$(wc -l < "$g_outfile") + assert_true [ "$line_count" -eq 2 ] + + # @测试步骤: 标准错误重定向到文件(2>) + # @预期结果: 错误信息写入指定文件 + local errfile="$g_tmpdir/err.txt" + ls /nonexistent_path_xyz 2> "$errfile" + assert_true test -s "$errfile" + + # @测试步骤: 标准输出和错误合并重定向(2>&1) + # @预期结果: 错误信息和正常输出均写入同一文件 + local combined="$g_tmpdir/combined.txt" + { echo "stdout_msg"; ls /nonexistent_xyz_path; } > "$combined" 2>&1 + grep -q "stdout_msg" "$combined" + assert_true [ $? -eq 0 ] + + # @测试步骤: 输入重定向(<) + # @预期结果: 从文件读取内容作为命令输入 + echo "input_content" > "$g_tmpdir/input.txt" + output=$(cat < "$g_tmpdir/input.txt") + assert_true [ "$output" = "input_content" ] + + # @测试步骤: Here Document(< /dev/null + assert_true [ $? -eq 0 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-loop-control.sh b/bash-loop-control.sh new file mode 100644 index 0000000..3ff401c --- /dev/null +++ b/bash-loop-control.sh @@ -0,0 +1,127 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-006-bash-loop-control +# @用例名称: bash-loop-control +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 循环控制功能,包括 for 循环、while 循环、until 循环、break/continue 控制以及 C 风格 for 循环等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: for 循环遍历列表并累加 + # @预期结果: 循环正确遍历所有元素,累加结果正确 + sum=0 + for i in 1 2 3 4 5; do + sum=$((sum + i)) + done + assert_true [ "$sum" -eq 15 ] + + # @测试步骤: C 风格 for 循环 + # @预期结果: C 风格循环正确执行 + count=0 + for (( i=0; i<5; i++ )); do + count=$((count + 1)) + done + assert_true [ "$count" -eq 5 ] + + # @测试步骤: for 循环使用 {start..end} 序列展开 + # @预期结果: 序列正确展开并循环 + items=() + for n in {1..4}; do + items+=("$n") + done + assert_true [ "${#items[@]}" -eq 4 ] + assert_true [ "${items[3]}" = "4" ] + + # @测试步骤: while 循环 + # @预期结果: while 循环在条件为假时退出,执行次数正确 + counter=0 + while [ "$counter" -lt 5 ]; do + counter=$((counter + 1)) + done + assert_true [ "$counter" -eq 5 ] + + # @测试步骤: until 循环 + # @预期结果: until 循环在条件为真时退出 + val=0 + until [ "$val" -ge 3 ]; do + val=$((val + 1)) + done + assert_true [ "$val" -eq 3 ] + + # @测试步骤: break 跳出循环 + # @预期结果: break 正确跳出循环 + result=0 + for i in 1 2 3 4 5; do + if [ "$i" -eq 3 ]; then + break + fi + result="$i" + done + assert_true [ "$result" -eq 2 ] + + # @测试步骤: continue 跳过本次循环 + # @预期结果: continue 正确跳过偶数,只累加奇数 + odd_sum=0 + for i in 1 2 3 4 5; do + if [ $((i % 2)) -eq 0 ]; then + continue + fi + odd_sum=$((odd_sum + i)) + done + assert_true [ "$odd_sum" -eq 9 ] + + # @测试步骤: for 循环遍历数组 + # @预期结果: 循环正确遍历数组所有元素 + arr=(a b c d) + arr_count=0 + for elem in "${arr[@]}"; do + arr_count=$((arr_count + 1)) + done + assert_true [ "$arr_count" -eq 4 ] + + # @测试步骤: while 循环读取命令输出(while read) + # @预期结果: 正确逐行读取并计数 + line_count=0 + while IFS= read -r line; do + line_count=$((line_count + 1)) + done < <(printf 'line1\nline2\nline3\n') + assert_true [ "$line_count" -eq 3 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-process-substitution.sh b/bash-process-substitution.sh new file mode 100644 index 0000000..bf15903 --- /dev/null +++ b/bash-process-substitution.sh @@ -0,0 +1,104 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-010-bash-process-substitution +# @用例名称: bash-process-substitution +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 进程替换和命令替换功能,包括 $()、反引号、<() 进程替换、>() 进程替换以及子 shell 特性等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: $() 命令替换捕获输出 + # @预期结果: 命令输出被正确捕获 + output=$(echo "captured") + assert_true [ "$output" = "captured" ] + + # @测试步骤: 嵌套命令替换 + # @预期结果: 嵌套命令替换正确求值 + output=$(echo $(echo "nested_value")) + assert_true [ "$output" = "nested_value" ] + + # @测试步骤: 命令替换保留多行输出(有换行符) + # @预期结果: 多行输出可以正确捕获并计数 + output=$(printf "a\nb\nc") + line_count=$(echo "$output" | wc -l) + assert_true [ "$line_count" -eq 3 ] + + # @测试步骤: 使用进程替换 <() 比较两个命令的输出 + # @预期结果: 进程替换文件描述符可以被 diff 使用 + diff <(echo -e "a\nb\nc") <(echo -e "a\nb\nc") > /dev/null 2>&1 + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用进程替换 <() 向 while read 传入动态数据 + # @预期结果: 进程替换数据被正确逐行读取 + count=0 + while IFS= read -r line; do + count=$((count + 1)) + done < <(printf "x\ny\nz\n") + assert_true [ "$count" -eq 3 ] + + # @测试步骤: 子 shell () 中修改变量不影响父 shell + # @预期结果: 子 shell 中的变量修改不传播到父 shell + parent_var="parent" + (parent_var="child"; assert_true [ "$parent_var" = "child" ]) + assert_true [ "$parent_var" = "parent" ] + + # @测试步骤: 子 shell 执行后退出码正确传递 + # @预期结果: 子 shell 中命令失败,退出码为非 0 + (exit 1) + assert_true [ $? -ne 0 ] + + # @测试步骤: 使用 {} 组合命令(当前 shell 执行) + # @预期结果: 组合命令在当前 shell 执行,可以修改变量 + group_var=0 + { group_var=42; } + assert_true [ "$group_var" -eq 42 ] + + # @测试步骤: 使用 $$ 获取当前进程 PID + # @预期结果: 当前进程 PID 是有效正整数 + pid=$$ + assert_true [ "$pid" -gt 0 ] + + # @测试步骤: 使用 $? 获取上一命令退出码 + # @预期结果: 成功命令退出码为 0 + true + last_ret=$? + assert_true [ "$last_ret" -eq 0 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-script-options.sh b/bash-script-options.sh new file mode 100644 index 0000000..ca0970b --- /dev/null +++ b/bash-script-options.sh @@ -0,0 +1,133 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-012-bash-script-options +# @用例名称: bash-script-options +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 脚本选项功能,包括 set -e(错误退出)、set -u(未定义变量报错)、set -o pipefail(管道错误捕获)、set -x(调试输出)以及 shopt 选项开关等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 测试 set -e 选项(遇错退出),在子 shell 中验证 + # @预期结果: set -e 开启后,命令失败导致子 shell 立即退出 + ( + set -e + false + echo "should_not_reach" + ) > /dev/null 2>&1 + assert_true [ $? -ne 0 ] + + # @测试步骤: 测试 set -u 选项(未定义变量报错),在子 shell 中验证 + # @预期结果: set -u 开启后,访问未定义变量导致错误退出 + ( + set -u + echo "$undefined_variable_xyz" + ) > /dev/null 2>&1 + assert_true [ $? -ne 0 ] + + # @测试步骤: 测试 set -o pipefail 选项 + # @预期结果: 管道中有命令失败时,整个管道返回非 0 + ( + set -o pipefail + false | true + ) > /dev/null 2>&1 + assert_true [ $? -ne 0 ] + + # @测试步骤: 测试 set -x 调试模式(输出命令追踪信息到 stderr) + # @预期结果: set -x 开启后,xtrace 输出到 stderr + local xtrace_output + xtrace_output=$( + set -x + x=1 + ) 2>&1 + echo "$xtrace_output" | grep -q "x=1" + assert_true [ $? -eq 0 ] + + # @测试步骤: 测试 set +e 关闭错误退出选项 + # @预期结果: set +e 关闭后,命令失败不导致脚本退出 + ( + set -e + set +e + false + echo "should_reach" + ) > /dev/null 2>&1 + assert_true [ $? -eq 0 ] + + # @测试步骤: 测试 shopt -s nullglob(无匹配时 glob 展开为空) + # @预期结果: 开启 nullglob 后,不匹配的 glob 展开为空数组而不是原字符串 + ( + shopt -s nullglob + files=( /nonexistent_path_xyz/*.xyz ) + echo "${#files[@]}" + ) > /dev/null 2>&1 + result=$( + shopt -s nullglob + files=( /nonexistent_path_xyz/*.xyz ) + echo "${#files[@]}" + ) + assert_true [ "$result" -eq 0 ] + + # @测试步骤: 测试 shopt -s extglob(扩展 glob 模式) + # @预期结果: extglob 开启后,?(pattern) 等扩展模式可正确匹配 + ( + shopt -s extglob + str="testfile.txt" + [[ "$str" == ?(test)file.txt ]] + ) + assert_true [ $? -eq 0 ] + + # @测试步骤: 验证 bash --version 返回版本信息 + # @预期结果: 命令执行成功并输出包含 bash 的版本信息 + bash --version > /dev/null 2>&1 + assert_true [ $? -eq 0 ] + output=$(bash --version 2>&1) + echo "$output" | grep -qi "bash" + assert_true [ $? -eq 0 ] + + # @测试步骤: 验证 bash -n 语法检查功能 + # @预期结果: 语法正确的脚本返回 0,语法错误返回非 0 + echo 'echo "valid script"' > "$g_tmpdir/valid.sh" + bash -n "$g_tmpdir/valid.sh" + assert_true [ $? -eq 0 ] + + echo 'if [ ; then echo bad; fi' > "$g_tmpdir/invalid.sh" + bash -n "$g_tmpdir/invalid.sh" > /dev/null 2>&1 + assert_true [ $? -ne 0 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-string-operations.sh b/bash-string-operations.sh new file mode 100644 index 0000000..812697d --- /dev/null +++ b/bash-string-operations.sh @@ -0,0 +1,106 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-009-bash-string-operations +# @用例名称: bash-string-operations +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 字符串处理功能,包括字符串拼接、比较、查找(grep)、分割(IFS)、printf 格式化以及 read 内置命令读取字符串等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 字符串拼接 + # @预期结果: 拼接结果正确 + str1="hello" + str2="_world" + combined="${str1}${str2}" + assert_true [ "$combined" = "hello_world" ] + + # @测试步骤: 字符串相等比较 + # @预期结果: 相等字符串比较返回真 + assert_true [ "abc" = "abc" ] + + # @测试步骤: 字符串不等比较 + # @预期结果: 不等字符串比较返回真 + assert_true [ "abc" != "xyz" ] + + # @测试步骤: 字符串字典序比较(< 和 >) + # @预期结果: 字典序比较正确 + [[ "apple" < "banana" ]] + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 printf 格式化字符串 + # @预期结果: 格式化输出正确 + output=$(printf "%-10s %05d" "name" 42) + echo "$output" | grep -q "name" + assert_true [ $? -eq 0 ] + echo "$output" | grep -q "00042" + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 IFS 分割字符串 + # @预期结果: 字符串按指定分隔符正确分割 + csv="one,two,three" + IFS=',' read -ra parts <<< "$csv" + assert_true [ "${parts[0]}" = "one" ] + assert_true [ "${parts[1]}" = "two" ] + assert_true [ "${parts[2]}" = "three" ] + + # @测试步骤: 使用 read 从 Here String 读取多个变量 + # @预期结果: read 正确分割并赋值给多个变量 + read -r first second third <<< "aa bb cc" + assert_true [ "$first" = "aa" ] + assert_true [ "$second" = "bb" ] + assert_true [ "$third" = "cc" ] + + # @测试步骤: 字符串包含检查(使用 [[ =~ ]]) + # @预期结果: 子串检查正确 + haystack="the quick brown fox" + [[ "$haystack" =~ "quick" ]] + assert_true [ $? -eq 0 ] + + # @测试步骤: 使用 tr 进行字符转换 + # @预期结果: 字符替换结果正确 + output=$(echo "hello world" | tr ' ' '_') + assert_true [ "$output" = "hello_world" ] + + # @测试步骤: 使用 printf 将数字转十六进制 + # @预期结果: 十六进制转换结果正确 + output=$(printf "%x" 255) + assert_true [ "$output" = "ff" ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/bash-variable-expansion.sh b/bash-variable-expansion.sh new file mode 100644 index 0000000..c9513ac --- /dev/null +++ b/bash-variable-expansion.sh @@ -0,0 +1,113 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-002-bash-variable-expansion +# @用例名称: bash-variable-expansion +# @用例级别: 2 +# @用例标签: bash +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 bash 变量展开功能,包括普通变量赋值、默认值展开、字符串截取、字符串替换、大小写转换等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + # @预置条件: 安装 bash 软件包 + assert_true yum install -y bash + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 普通变量赋值和展开 + # @预期结果: 变量值正确展开 + myvar="hello" + output="${myvar}" + assert_true [ "$output" = "hello" ] + + # @测试步骤: 使用 ${var:-default} 展开默认值(变量未设置时) + # @预期结果: 返回默认值 + unset undefined_var + output="${undefined_var:-default_value}" + assert_true [ "$output" = "default_value" ] + + # @测试步骤: 使用 ${var:-default} 展开(变量已设置时) + # @预期结果: 返回变量值而非默认值 + set_var="actual" + output="${set_var:-default_value}" + assert_true [ "$output" = "actual" ] + + # @测试步骤: 字符串长度 ${#var} + # @预期结果: 返回正确的字符串长度 + str="hello" + len="${#str}" + assert_true [ "$len" -eq 5 ] + + # @测试步骤: 字符串截取 ${var:offset:length} + # @预期结果: 正确截取子字符串 + str="hello_world" + output="${str:6:5}" + assert_true [ "$output" = "world" ] + + # @测试步骤: 删除前缀匹配 ${var#pattern} + # @预期结果: 正确删除最短前缀 + path="/usr/local/bin" + output="${path#/usr/}" + assert_true [ "$output" = "local/bin" ] + + # @测试步骤: 删除后缀匹配 ${var%pattern} + # @预期结果: 正确删除最短后缀 + filename="test.tar.gz" + output="${filename%.gz}" + assert_true [ "$output" = "test.tar" ] + + # @测试步骤: 字符串替换 ${var/pattern/replacement}(替换第一个) + # @预期结果: 只替换第一个匹配 + str="aabbaa" + output="${str/aa/XX}" + assert_true [ "$output" = "XXbbaa" ] + + # @测试步骤: 字符串全局替换 ${var//pattern/replacement} + # @预期结果: 替换所有匹配 + str="aabbaa" + output="${str//aa/XX}" + assert_true [ "$output" = "XXbbXX" ] + + # @测试步骤: 大写转换 ${var^^} + # @预期结果: 字符串全部转换为大写 + str="hello" + output="${str^^}" + assert_true [ "$output" = "HELLO" ] + + # @测试步骤: 小写转换 ${var,,} + # @预期结果: 字符串全部转换为小写 + str="HELLO" + output="${str,,}" + assert_true [ "$output" = "hello" ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### -- Gitee